Gorm和Mysql驱动的安装
打开终端,输入下列命令即可:
go get gorm.io/driver/mysql
go get gorm.io/gorm
Gorm连接数据库
示例
package main
import (
"fmt"
"github.com/sirupsen/logrus"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func init() {
//数据库连接信息
username := "root"
password := "123456"
databasename := "gorm"
localHost := "localhost"
port := 3306
dns := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local",
username, password, localHost, port, databasename)
db, err := gorm.Open(mysql.Open(dns))
if err != nil {
logrus.Error("数据库连接失败", err)
}
fmt.Println("数据库连接成功", db)
}
func main() {
}
数据库连接的细节
- 跳过默认事务
为了保证数据一致性,Gorm会在事务中去执行去执行增删查改,如果我们没有这个需求可以选择跳过默认事务:
db, err := gorm.Open(mysql.Open(dns),&gorm.Config{SkipDefaultTransaction: true})
- 命名策略
在grom中默认表名是复数,字段是单数,比如下面我们创建一张student
表,代码是这样的:
package main
import (
"fmt"
"github.com/sirupsen/logrus"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var dB *gorm.DB
type Student struct {
Name string
Age int
Sex string
}
func init() {
//数据库连接信息
username := "root"
password := "ba161754"
databasename := "gorm"
localHost := "localhost"
port := 3306
dns := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local",
username, password, localHost, port, databasename)
db, err := gorm.Open(mysql.Open(dns), &gorm.Config{SkipDefaultTransaction: true})
if err != nil {
logrus.Error("数据库连接失败", err)
}
dB = db
}
func main() {
err := dB.AutoMigrate(Student{})
if err != nil {
logrus.Error("数据库迁移失败", err)
}
fmt.Println("创建表成功")
}
创建出来的表是这样的:
当然我们也可以尝试修改这种命名策略:
db, err := gorm.Open(mysql.Open(dns), &gorm.Config{SkipDefaultTransaction: true,
NamingStrategy: schema.NamingStrategy{ //
TablePrefix: "t_", //表名前缀
SingularTable: false, //禁用表名复数
NoLowerCase: false, //禁用小写
}})
- 日志显示
func initLogger() {
var mysqlLogger logger.Interface
mysqlLogger = logger.Default.LogMode(logger.Info) //设置日志打印级别
mysqlLogger = logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // (日志输出的目标,前缀和日志包含的内容)
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: logger.Info, // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound(记录未找到)错误
Colorful: true, // 使用彩色打印
},
)
dB.Logger = mysqlLogger
}
完整代码,仅供参考:
package main
import (
"fmt"
"github.com/sirupsen/logrus"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
"log"
"os"
"time"
)
var dB *gorm.DB
type Student struct {
Name string
Age int
Sex string
}
func ConnectDB() {
//数据库连接信息
username := "root"
password := "ba161754"
databasename := "gorm"
localHost := "localhost"
port := 3306
var err error
dns := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local",
username, password, localHost, port, databasename)
dB, err = gorm.Open(mysql.Open(dns), &gorm.Config{SkipDefaultTransaction: true,
NamingStrategy: schema.NamingStrategy{ //
TablePrefix: "t_", //表名前缀
SingularTable: false, //禁用表名复数
NoLowerCase: false, //禁用小写
}})
if err != nil {
logrus.Error("数据库连接失败", err)
}
}
func initLogger() {
var mysqlLogger logger.Interface
mysqlLogger = logger.Default.LogMode(logger.Info) //设置日志打印级别
mysqlLogger = logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // (日志输出的目标,前缀和日志包含的内容)
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: logger.Info, // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound(记录未找到)错误
Colorful: true, // 使用彩色打印
},
)
dB.Logger = mysqlLogger
}
func init() {
ConnectDB()
initLogger()
}
func main() {
err := dB.AutoMigrate(Student{})
if err != nil {
logrus.Error("数据库迁移失败", err)
}
fmt.Println("创建表成功")
}
模型定义
模型定义示例
模型是使用普通结构体定义的。 这些结构体可以包含具有基本Go类型、指针或这些类型的别名,甚至是自定义类型(只需要实现 database/sql 包中的Scanner和Valuer接口)我们来看一下Gorm给出的user
模型示例:
type User struct {
ID uint // Standard field for the primary key
Name string // 一个常规字符串字段
Email *string // 一个指向字符串的指针, allowing for null values
Age uint8 // 一个未签名的8位整数
Birthday *time.Time // A pointer to time.Time, can be null
MemberNumber sql.NullString // Uses sql.NullString to handle nullable strings
ActivatedAt sql.NullTime // Uses sql.NullTime for nullable time fields
CreatedAt time.Time // 创建时间(由GORM自动管理)
UpdatedAt time.Time // 最后一次更新时间(由GORM自动管理)
}
这里常见的uint
这种类型就不做过多介绍了,这里主要是 有两个类型我们这里进行一下介绍:
*string(指针类型)
:如果我们在这里使用string
类型的话,这里我们是可以写空值的,如果我们用string
类型是不允许出现空值的sql.NullString
:sql.NullString
是 Go 语言标准库中的一个数据类型,位于 database/sql 包中。它用于表示数据库中可能为 NULL 的字符串值。它由两个字段组成:String
用于保存字符串值(如果不为 NULL),Valid
是一个布尔标志,指示字符串值是否为 NULL。在与允许字符串列包含 NULL 值的数据库一起工作时,这种类型特别有用。
type NullString struct {
String string
Valid bool // Valid is true if String is not NULL
}
gorm.Model
在开始介绍gorm.Model
之前,我们先讲一下几条在gorm
的约定:
-主键:GORM 使用一个名为ID 的字段作为每个模型的默认主键。
-
表名:默认情况下,GORM 将结构体名称转换为 snake_case 并为表名加上复数形式。 例如,一个 User 结构体在数据库中的表名变为 users 。
-
列名:GORM 自动将结构体字段名称转换为 snake_case 作为数据库中的列名。
-
时间戳字段:GORM使用字段 CreatedAt 和 UpdatedAt 来自动跟踪记录的创建和更新时间。
而在grom
中存在gorm.Model
这一预定义的结构体,我们可以将它直接嵌入我们所定义的结构体中,这保证了不同模型之间保持一致性并利用GORM
内置的约定,gorm.model
的定义如下:
type Model struct {
ID uint `gorm:"primarykey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt DeletedAt `gorm:"index"`
}
它主要包含以下字段:
- ID :每个记录的唯一标识符(主键)。
- CreatedAt :在创建记录时自动设置为当前时间。
- UpdatedAt:每当记录更新时,自动更新为当前时间。
- DeletedAt:用于软删除(将记录标记为已删除,而实际上并未从数据库中删除)。
字段标签
在gorm
中我们一般使用字段标签来表示字段的类型,常见的字段类型主要有以下几种:
type
:定义字段类型size
:字段大小column
自定义别名primaryKey
将列定义为主键unique
将列定义为唯一键default
定义列的默认值not null
不可为空embedded
嵌套字段embeddedPrefix
嵌套字段前缀comment
注释
示例:
type StudentInfo struct {
Email *string `gorm:"size:32"` // 使用指针是为了存空值
Addr string `gorm:"column:y_addr;size:16"`
Gender bool `gorm:"default:true"`
}
type Student struct {
Name string `gorm:"type:varchar(12);not null;comment:用户名"`
UUID string `gorm:"primaryKey;unique;comment:主键"`
Info StudentInfo `gorm:"embedded;embeddedPrefix:s_"`
}