安装依赖
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
代码
package main
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func main() {
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
db, _ := gorm.Open(mysql.New(mysql.Config{
DSN: "root:Ljr19981204@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local", // 账号密码地址端口
}), &gorm.Config{
})
fmt.Println(db)
}
MySQL驱动高级配置
package main
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func main() {
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
db, _ := gorm.Open(mysql.New(mysql.Config{
DSN: "root:Ljr19981204@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local", // 账号密码地址端口
DefaultStringSize: 256, // string 类型字段的默认长度
DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
}), &gorm.Config{
// ...gorm配置
})
fmt.Println(db)
}
GORM配置
db, _ := gorm.Open(mysql.New(mysql.Config{
// ...MySQL配置
}), &gorm.Config{
SkipDefaultTransaction: true, // 跳过默认事物
// GORM 允许用户通过覆盖默认的NamingStrategy来更改命名约定
NamingStrategy: schema.NamingStrategy{
TablePrefix: "t_", // 表名前缀,`User`表为`t_users`
SingularTable: true, // 使用单数表名,启用该选项后,`User` 表将是`user`
},
// 在 AutoMigrate 或 CreateTable 时,GORM 会自动创建外键约束,若要禁用该特性,可将其设置为 true
DisableForeignKeyConstraintWhenMigrating: true,
// 更改创建时间使用的函数
NowFunc: func() time.Time {
return time.Now().Local()
},
})
连接池配置
// 直接通过上面连接得到的db,调用DB()函数返回即可设置
sqlDB, _ := db.DB()
// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)
// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(100)
// SetConnMaxLifetime 设置了连接可复用的最大时间。
sqlDB.SetConnMaxLifetime(time.Hour)
模型
模型就是GO语言中的Struct结构体+标签
约定
GORM 倾向于约定,而不是配置。默认情况下,GORM 使用 ID
作为主键,使用结构体名的 蛇形复数
作为表名,字段名的 蛇形
作为列名,并使用 CreatedAt
、UpdatedAt
字段追踪创建、更新时间
gorm.Model
GORM 定义一个 gorm.Model
结构体,其包括字段 ID
、CreatedAt
、UpdatedAt
、DeletedAt
// gorm.Model 的定义
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
可以将它嵌入到自定义的结构体中,以包含这几个字段
嵌入结构体
有如下自定义结构体User
type User struct {
Name string
}
对于匿名字段,GORM 会将其字段包含在父结构体中,例如:
type User struct {
gorm.Model // 将GORM定义的gorm.Model结构体嵌入到User结构体中
Name string
}
// 等效于
type User struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
Name string
}
对于正常的结构体字段,也可以通过标签 embedded
将其嵌入,例如:
type Author struct {
Name string
Email string
}
type Blog struct {
ID int
Upvotes int32
Author Author `gorm:"embedded"`
}
// 等效于
type Blog struct {
ID int64
Name string
Email string
Upvotes int32
}
字段标签
声明 model 时,tag 是可选的,GORM 支持以下 tag: tag 名大小写不敏感,但建议使用 camelCase
风格。
标签列表:
标签名 | 说明 |
---|---|
column | 指定 db 列名 |
type | 列数据类型,推荐使用兼容性好的通用类型,例如:所有数据库都支持 bool、int、uint、float、string、time、bytes 并且可以和其他标签一起使用,例如:not null、size, autoIncrement… 像 varbinary(8) 这样指定数据库数据类型也是支持的。在使用指定数据库数据类型时,它需要是完整的数据库数据类型,如:MEDIUMINT UNSIGNED not NULL AUTO\_INCREMENT |
size | 指定列大小,例如:size:256 |
primaryKey | 指定列为主键 |
unique | 指定列为唯一 |
default | 指定列的默认值 |
precision | 指定列的精度 |
scale | 指定列大小 |
not null | 指定列为 NOT NULL |
autoIncrement | 指定列为自动增长 |
autoIncrementIncrement | 自动步长,控制连续记录之间的间隔 |
embedded | 嵌套字段 |
embeddedPrefix | 嵌入字段的列名前缀 |
autoCreateTime | 创建时追踪当前时间,对于 int 字段,它会追踪秒级时间戳,您可以使用 nano/milli 来追踪纳秒、毫秒时间戳,例如:autoCreateTime:nano |
autoUpdateTime | 创建/更新时追踪当前时间,对于 int 字段,它会追踪秒级时间戳,您可以使用 nano/milli 来追踪纳秒、毫秒时间戳,例如:autoUpdateTime:milli |
index | 根据参数创建索引,多个字段使用相同的名称则创建复合索引,查看 索引获取详情 |
uniqueIndex | 与 index相同,但创建的是唯一索引 |
check | 创建检查约束,例如 check:age > 13,查看 约束获取详情 |
<- | 设置字段写入的权限, <-:create 只创建、<-:update只更新、<-:false无写入权限、<-创建和更新权限 |
-> | 设置字段读的权限,->:false无读权限 |
- | 忽略该字段,-无读写权限 |
comment | 迁移时为字段添加注释 |
示例:
type User struct {
Model gorm.Model `gorm:"embedded;embeddedPrefix:gorm_"` // 嵌套字段,且嵌套字段前缀为gorm_
Name string `gorm:"column:username;comment:用户名"` // 指定数据库列名为username,注释为用户名
Email *string `gorm:"unique;not null;comment:邮箱"` // 指定列唯一,且为not null
Age uint8 `gorm:"default:18;comment:年龄"` // 指定默认值为18
}
表迁移(自动生成数据表)
AutoMigrate
直接通过db.AutoMigrate即可根据模型生成数据表,使用上述配置的MySQL和GORM以及User模型生成的数据表如下所示,结构体的每个属性都对应到数据表中的字段,且设置的字段标签也对应生效。
Migrator 接口
AutoMigrate方法只能简单的生成数据表,Migrator 接口为每个数据库提供了统一的 API 接口,可用来为您的数据库构建独立迁移。
// 获取当前数据库名
db.Migrator().CurrentDatabase()
表操作
// 为 `User` 创建表
db.Migrator().CreateTable(&User{})
// 将 "ENGINE=InnoDB" 添加到创建 `User` 的 SQL 里去
db.Set("gorm:table_options", "ENGINE=InnoDB").Migrator().CreateTable(&User{})
// 检查 `User` 对应的表是否存在
db.Migrator().HasTable(&User{})
db.Migrator().HasTable("users")
// 如果存在表则删除(删除时会忽略、删除外键约束)
db.Migrator().DropTable(&User{})
db.Migrator().DropTable("users")
// 重命名表
db.Migrator().RenameTable(&User{}, &UserInfo{})
db.Migrator().RenameTable("users", "user_infos")
列操作
type User struct {
Name string
}
// 添加 name 字段
db.Migrator().AddColumn(&User{}, "Name")
// 删除 name 字段
db.Migrator().DropColumn(&User{}, "Name")
// 修改 name 字段
db.Migrator().AlterColumn(&User{}, "Name")
// 检查字段是否存在
db.Migrator().HasColumn(&User{}, "Name")
type User struct {
Name string
NewName string
}
// 重命名字段
db.Migrator().RenameColumn(&User{}, "Name", "NewName")
db.Migrator().RenameColumn(&User{}, "name", "new_name")
// 获取字段类型
db.Migrator().ColumnTypes(&User{}) ([]*sql.ColumnType, error)
索引操作
type User struct {
gorm.Model
Name string `gorm:"size:255;index:idx_name,unique"`
}
// 为 Name 字段创建索引
db.Migrator().CreateIndex(&User{}, "Name")
db.Migrator().CreateIndex(&User{}, "idx_name")
// 为 Name 字段删除索引
db.Migrator().DropIndex(&User{}, "Name")
db.Migrator().DropIndex(&User{}, "idx_name")
// 检查索引是否存在
db.Migrator().HasIndex(&User{}, "Name")
db.Migrator().HasIndex(&User{}, "idx_name")
type User struct {
gorm.Model
Name string `gorm:"size:255;index:idx_name,unique"`
Name2 string `gorm:"size:255;index:idx_name_2,unique"`
}
// 修改索引名
db.Migrator().RenameIndex(&User{}, "Name", "Name2")
db.Migrator().RenameIndex(&User{}, "idx_name", "idx_name_2")
本文参与了思否技术征文,欢迎正在阅读的你也加入。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。