//结构体示例 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 }
默认情况下,GORM 使用 ID 作为主键,使用结构体名的 蛇形复数 作为表名,字段名的 蛇形 作为列名,并使用 CreatedAt、UpdatedAt 字段追踪创建、更新时间
type User struct { Name string`gorm:"<-:create"`// allow read and create Name string`gorm:"<-:update"`// allow read and update Name string`gorm:"<-"`// allow read and write (create and update) Name string`gorm:"<-:false"`// allow read, disable write permission Name string`gorm:"->"`// readonly (disable write permission unless it configured) Name string`gorm:"->;<-:create"`// allow read and create Name string`gorm:"->:false;<-:create"`// createonly (disabled read from db) Name string`gorm:"-"`// ignore this field when write and read with struct Name string`gorm:"-:all"`// ignore this field when write, read and migrate with struct Name string 'gorm:“-:migration”' // ignore this field when migrate with struct }
如果您想要保存 UNIX(毫/纳)秒时间戳,而不是 time,您只需简单地将 time.Time 修改为 int 即可
type User struct { CreatedAt time.Time // 在创建时,如果该字段值为零值,则使用当前时间填充 UpdatedAt int// 在创建时该字段值为零值或者在更新时,使用当前时间戳秒数填充 Updated int64`gorm:"autoUpdateTime:nano"`// 使用时间戳填纳秒数充更新时间 Updated int64`gorm:"autoUpdateTime:milli"`// 使用时间戳毫秒数填充更新时间 Created int64`gorm:"autoCreateTime"`// 使用时间戳秒数填充创建时间 }
1.4、嵌入结构体
匿名字段,GORM 会将其字段包含在父结构体中,例如:
// gorm.Model 的定义 type Model struct { ID uint`gorm:"primaryKey"` CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"` } //实际的model类型 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 将其嵌入,例如:
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 来为 db 中的字段名添加前缀,例如:
type Blog struct { ID int Author Author `gorm:"embedded;embeddedPrefix:author_"` Upvotes int32 } // 等效于 type Blog struct { ID int64 AuthorName string AuthorEmail string Upvotes int32 }
1.5、字段标签
声明 model 时,tag 是可选的,GORM 支持以下 tag: tag 名大小写不敏感,但建议使用 camelCase 风格
specifies serializer for how to serialize and deserialize data into db, e.g: serializer:json/gob/unixtime –制定序列化器
size
specifies column data size/length, e.g: size:256 指定一个单元格长度
primaryKey
specifies column as primary key–指定主键
unique
specifies column as unique–指定唯一
default
specifies column default value–指定默认值
precision
specifies column precision–指定列的数据的精度
scale
specifies column scale–ƒ
not null
specifies column as NOT NULL–列非空
autoIncrement
specifies column auto incrementable–列自增
autoIncrementIncrement
auto increment step, controls the interval between successive column values–自增步长
embedded
embed the field–内嵌对象
embeddedPrefix
column name prefix for embedded fields–内嵌对象前缀
autoCreateTime
track current time when creating, for int fields, it will track unix seconds, use value nano/milli to track unix nano/milli seconds, e.g: autoCreateTime:nano
autoUpdateTime
track current time when creating/updating, for int fields, it will track unix seconds, use value nano/milli to track unix nano/milli seconds, e.g: autoUpdateTime:milli –自动更新时间(time.Time时间戳、int毫秒数)
index
create index with options, use same name for multiple fields creates composite indexes, refer Indexes for details–索引
type Config struct { // GORM perform single create, update, delete operations in transactions by default to ensure database data integrity // You can disable it by setting `SkipDefaultTransaction` to true SkipDefaultTransaction bool // NamingStrategy tables, columns naming strategy NamingStrategy schema.Namer // FullSaveAssociations full save associations FullSaveAssociations bool // Logger Logger logger.Interface // NowFunc the function to be used when creating a new timestamp NowFunc func() time.Time // DryRun generate sql without execute DryRun bool // PrepareStmt executes the given query in cached statement PrepareStmt bool // DisableAutomaticPing DisableAutomaticPing bool // DisableForeignKeyConstraintWhenMigrating DisableForeignKeyConstraintWhenMigrating bool // DisableNestedTransaction disable nested transaction DisableNestedTransaction bool // AllowGlobalUpdate allow global update AllowGlobalUpdate bool // QueryFields executes the SQL query with all fields of the table QueryFields bool // CreateBatchSize default create batch size CreateBatchSize int
// works because destination struct is passed in db.First(&user) // SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1
// works because model is specified using `db.Model()` result := map[string]interface{}{} db.Model(&User{}).First(&result) // SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1
不生效写法
// doesn't work result := map[string]interface{}{} db.Table("users").First(&result)
不指定主键(自动使用结构体第一个字短)
// no primary key defined, results will be ordered by first field (i.e., `Code`) type Language struct { Code string Name string } db.First(&Language{}) // SELECT * FROM `languages` ORDER BY `languages`.`code` LIMIT 1
db.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "id"}}, DoUpdates: clause.Assignments(map[string]interface{}{"role": "user"}), }).Create(&users) // INSERT INTO `users` *** ON DUPLICATE KEY UPDATE ***; MySQL
执行SQL语句
db.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "id"}}, DoUpdates: clause.Assignments(map[string]interface{}{"count": gorm.Expr("GREATEST(count, VALUES(count))")}), }).Create(&users) // INSERT INTO `users` *** ON DUPLICATE KEY UPDATE `count`=GREATEST(count, VALUES(count));
在`id`冲突时,将列更新为新值
db.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "id"}}, DoUpdates: clause.AssignmentColumns([]string{"name", "age"}), }).Create(&users) // INSERT INTO `users` *** ON DUPLICATE KEY UPDATE `name`=VALUES(name),`age=VALUES(age); MySQL
除了主键全部进行更新
db.Clauses(clause.OnConflict{ UpdateAll: true, }).Create(&users) // INSERT INTO "users" *** ON CONFLICT ("id") DO UPDATE SET "name"="excluded"."name", "age"="excluded"."age", ...;
BaiYZ 2022/6/28 下午4:18:09
Variables declared without an explicit initial value are given their zero value.