一、结构体与数据库表映射
GORM 通过 Go 结构体(Model)与数据库表建立映射关系,其核心规则如下:
-
表名规则:
- 默认将结构体名称转换为蛇形复数形式作为表名(如
User→users)。 - 可通过
TableName()方法或db.Table("custom_name")自定义表名
- 默认将结构体名称转换为蛇形复数形式作为表名(如
func (User) TableName() string { return "user" }
- 字段映射:
- 结构体字段名默认转为蛇形小写作为列名(如
CreatedTime→created_time)。 - 通过
gorm:"column:custom_name"标签自定义列名。 - 使用
gorm:"primaryKey"定义主键,gorm:"index"创建索引
type User struct {
ID uint `gorm:"primaryKey"`
UserName string `gorm:"column:user_name;index"` }
二、数据库连接与迁移
-
连接数据库:
- 使用
gorm.Open()初始化连接,需指定驱动(如 MySQL、PostgreSQL)和 DSN(数据源名称)。 - 示例(MySQL):
- 使用
dsn := "user:pass@tcp(localhost:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
配置连接池:
sqlDB, _ := db.DB() sqlDB.SetMaxIdleConns(10) // 空闲连接数
sqlDB.SetMaxOpenConns(100) // 最大连接数
- 数据迁移:
- 自动迁移:
AutoMigrate根据结构体自动创建/更新表(不删除未使用列)。
db.AutoMigrate(&User{}, &Product{})
- 手动迁移:通过
Migrator接口精细控制(如创建表、修改列):
db.Migrator().CreateTable(&User{})
db.Migrator().RenameColumn(&User{}, "old_name", "new_name")
三、关联关系详解
一对一(One-to-One) :
- Belongs To(属于) :外键在当前模型中。
// 一对一关联实现方式一
type User struct {
ID uint `gorm:"primarykey"`
Name string `gorm:"type:varchar(255);unique"`
Nationality string `gorm:"type:varchar(255)"`
Masterpiece string `gorm:"type:varchar(255)"`
}
type Info struct {
ID uint `gorm:"primarykey"`
Birth string `gorm:"type:varchar(255)"`
Elapse string `gorm:"type:varchar(255)"`
UserID int64
User User
}
当只执行结构体Info数据查询时,由于设有属性User,对应User信息允许写入结构体Info的属性User。当只执行结构体User数据查询时,由于User没有属性与Info关联,因此无法将对应Info信息写入结构体User中
- Has One(拥有) :外键在关联模型中。
// 一对一关联实现方式二
type User1 struct {
ID uint `gorm:"primarykey"`
Name string `gorm:"type:varchar(255);unique"`
Nationality string `gorm:"type:varchar(255)"`
Masterpiece string `gorm:"type:varchar(255)"`
Info1 Info1
}
type Info1 struct {
ID uint `gorm:"primarykey"`
Birth string `gorm:"type:varchar(255)"`
Elapse string `gorm:"type:varchar(255)"`
User1ID int64
}
结构体User1和Info1的一对一关联在Gorm官方文档视为Has One类型,当只执行结构体Info1数据查询时,由于设有属性User1ID,它是结构体User1的主键id信息,再通过主键执行结构体User1数据查询就能得到响应信息。当只执行结构体User1数据查询时,由于设有属性Info1,对应Info1信息允许写入结构体User1 的属性Info1中
一对多(One-to-Many) :
- 外键在关联模型中,主模型通过切片持有多个关联对象。
// 一对多关联
type User struct {
ID uint `gorm:"primarykey"`
Name string `gorm:"type:varchar(255);unique"`
Nationality string `gorm:"type:varchar(255)"`
Program []Program
}
type Program struct {
ID uint `gorm:"primarykey"`
Name string `gorm:"type:varchar(255)"`
UserID int64
}
分析上述示例:一对多关联在一对一关联Has One类型的基础上将关联属性的数据类型改为切片格式即可,如结构体User的关联属性 Program 以[]Program表示。
多对多(Many-to-Many) :
- 通过中间表自动管理关联,使用
many2many标签。
// 多对多关联
type User struct {
ID uint `gorm:"primarykey"`
Name string `gorm:"type:varchar(255);unique"`
Nationality string `gorm:"type:varchar(255)"`
Program []Program `gorm:"many2many:user_program"`
}
type Program struct {
ID uint `gorm:"primarykey"`
Name string `gorm:"type:varchar(255)"`
}
在数据库中分别创建数据表 user user_program program,数据表的多对多关联在某模型中设置关联属性,数据类型为切片格式并且设置结构体标签声明为多对多关联,如结构体User和Program ,其数据类型为[]Program ,结构体标签为many2many:user_program,其中user_program可自行命名,它是程序自行创建数据表,用于管理多对多关联数据