gorm数据库对应关系

3 阅读3分钟

一、结构体与数据库表映射

GORM 通过 Go 结构体(Model)与数据库表建立映射关系,其核心规则如下:

  1. 表名规则

    • 默认将结构体名称转换为蛇形复数形式作为表名(如 User → users)。
    • 可通过 TableName() 方法或 db.Table("custom_name") 自定义表名
func (User) TableName() string { return "user" }
  1. 字段映射
  • 结构体字段名默认转为蛇形小写作为列名(如 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"` }

二、数据库连接与迁移

  1. 连接数据库

    • 使用 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) // 最大连接数
  1. 数据迁移
  • 自动迁移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可自行命名,它是程序自行创建数据表,用于管理多对多关联数据