Skip to content
On this page

模型定义

模型定义

模型是标准的struct,由Go的基本数据类型、实现了ScannerValuer接口的自定义类型及其指针或别名组成

例如:

Go
type User struct {
  ID           uint
  Name         string
  Email        *string
  Age          uint8
  Birthday     *time.Time
  MemberNumber sql.NullString
  ActivatedAt  sql.NullTime
  CreatedAt    time.Time
  UpdatedAt    time.Time
}

WARNING

结构体小写属性不会生成字段

约定

  • gorm默认使用ID作为主键

命名策略

gorm采用的命名策略:

  • 表名蛇形复数

  • 字段名蛇形单数

例如结构体如下:

Go
type User struct {
	ID       uint
	UserName string 
	Age      int
	Email    string
}

通过gorm生成的表结构如下

sql
CREATE TABLE users
(
    id        bigint UNSIGNED AUTO_INCREMENT
        PRIMARY KEY,
    user_name longtext NULL,
    age       bigint   NULL,
    email     longtext NULL
);

如上所示:

  • 结构体名称User生成的表名为users
  • 字段名称都小写,有驼峰(UserName)的字段名称被转换为蛇形(user_name)

自定义表/字段名

如果想自定义表名,可以通过以下方法

  • 实现TableName方法,这种方法只会修改当前设置的表
Go
type User struct {
	ID       uint
	UserName string 
	Age      int   
	Email    string 
}

// TableName 会将 User 的表名重写为 `customUser`
func (User) TableName() string {
	return "customUser"
}
  • 修改连接数据库时的配置,全局修改,所有表命名规则都会修改
Go
db, err := gorm.Open(mysql.Open(dbUrl), &gorm.Config{
  NamingStrategy: schema.NamingStrategy{
    // TablePrefix: "lyb_", // 生成的表名前缀,User结构体生成的表名为lyb_users
    // SingularTable: true, // 使用单数表名,设置为true后,User结构体生成的表名为user,而不是users
    // NoLowerCase: true, // 跳过转换蛇形命名
    // NameReplacer: strings.NewReplacer("User", "Cid"), // 名称替换,执行gorm名称替换策略之前,将User替换为Cid  
  },
})

gorm.Model

  • GORM定义了一个gorm.Model结构体,其包括字段IDCreatedAtUpdatedAtDeletedAt
Go
// gorm.Model 的定义
type Model struct {
  ID        uint           `gorm:"primaryKey"`
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt gorm.DeletedAt `gorm:"index"`
}

高级选项

嵌套结构体

  • 对于匿名字段GORM会将其字段包含在父结构体中,例如:
Go
type User struct {
  gorm.Model
  Name string
}
// 等效于
type User struct {
  ID        uint           `gorm:"primaryKey"`
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt gorm.DeletedAt `gorm:"index"`
  Name string
}
  • 对于普通的结构体,可以使用embedded标签
Go
type Author struct {
    Name  string
    Email string
}

type Blog struct {
  ID      int
  Author  Author `gorm:"embedded"`
  Upvotes int32
}
// 等效于
type Blog struct {
  ID    int64
  Name  string
  Email string
  Upvotes  int32
}
  • 可以使用标签embeddedPrefix添加嵌套结构体字段的名称
Go
type Author struct {
    Name  string
    Email string
}

type Blog struct {
  ID      int
  Author  Author `gorm:"embedded;embeddedPrefix:author_"`
  Upvotes int32
}
// 等同于如下所示
type Blog struct {
  ID          int64
  AuthorName  string
  AuthorEmail string
  Upvotes     int32
}

设置时间格式

  • GORM约定使用CreatedAtUpdatedAt 追踪创建/更新时间,格式为time.Time(1998-06-16 12:20:57.919),如果想用时间戳表示,可以将类型修改为int类型,或者使用autoCreateTimeautoUpdateTime等标签

例如

Go
type User struct {
  CreatedAt time.Time // 在创建时,如果该字段值为零值,则使用当前时间填充
  UpdatedAt int       // 在创建时该字段值为零值或者在更新时,使用当前时间戳秒数填充
  Updated   int64 `gorm:"autoUpdateTime:nano"` // 使用时间戳纳秒数填充更新时间
  Updated   int64 `gorm:"autoUpdateTime:milli"` // 使用时间戳毫秒数填充更新时间
  Created   int64 `gorm:"autoCreateTime"`      // 使用时间戳秒数填充创建时间
}

字段标签

  • column:自定义列名

  • type列数据类型,例如:boolintuintfloatstringtimebytes

  • size:定义列数据类型的大小长度

  • primaryKey:将列定义为主键

  • unique:将列定义为唯一键

  • default:定义列的默认值

  • not null:指定列为NOT NULL,不可为空

  • embedded:嵌套字段

  • embeddedPrefix:嵌入字段的列名前缀

  • comment:列的注释

  • -:忽略这个字段,-:没有读/写权限;-:migration:没有迁移权限;-:all:没有读/写/迁移权限

自动生成表结构

  • 使用AutoMigrate来实现

TIP

AutoMigrate的逻辑是只新增不删除不修改,但是如果修改了字段大小(size)会同步修改)

Go
type Teacher struct {
	gorm.Model
	Name   string `gorm:"type:varchar(32)"`
	Age    uint8
	Gender uint8
}

DB.AutoMigrate(&Teacher{})