gorm创建记录

1.  简单创建记录

1
2
3
4
5
user := User{Name: "李四", Age: 88, Birthday: time.Now()}
ret := db.Create(&user)  // 通过数据的指针来创建
fmt.Println(user.ID)  // 返回插入数据的主键
fmt.Println(ret.Error)  // 返回错误
fmt.Println(ret.RowsAffected)  // 插入数据的条数

  

2.  用指定的字段创建记录

1
user := User{Name: "李四3", Age: 19}db.Debug().Select("name", "age").Create(&user)

  

3. 排除指定的字段创建记录

1
2
user := User{Birthday: time.Now(), Name: "李四", Age: 10}
db.Debug().Omit("name", "age").Create(&user)

  

4.  批量插入

1
2
3
4
5
6
7
// 批量插入1
var users = []User{{Name: "04"}, {Name: "05"}, {Name: "06"}}
db.Create(&users)
 
// 批量插入2:  使用 CreateInBatches 分批创建时,你可以指定每批的数量
var users = []User{{Name: "07"}, {Name: "08"}, {Name: "09"}}
db.CreateInBatches(users, 2)

  

5.  创建钩子,插入前的钩子 BeforeCreate

1
2
3
4
5
6
7
8
9
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
    u.UUID = uuid.NewV4()
 
    if u.Role == "admin" {
        fmt.Println("执行失败了")
        return errors.New("invalid role")
    }
    return
}

  如果您想跳过 钩子 方法,您可以使用 SkipHooks 会话模式

1
db.Session(&gorm.Session{SkipHooks: true}).Create(&user)

  

6.  根据Map创建

1
2
3
4
5
6
7
8
db.Model(&User{}).Create(map[string]interface{}{
  "Name": "jinzhu", "Age": 18,
})
 
db.Model(&User{}).Create([]map[string]interface{}{
  {"Name": "jinzhu_1", "Age": 18},
  {"Name": "jinzhu_2", "Age": 20},
})

  注意:根据map创建记录的时候,不会走钩子方法

7.  关联创建

  创建关联数据时,如果关联值是非零值,这些关联会被upsert,且它们的hook方法也会被调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
type BaseModel struct {
    Age uint8
    Address string
    UserID uint
}
func (b *BaseModel) BeforeCreate(tx *gorm.DB) (err error) {
    fmt.Println("BaseModel 的 BeforeCreate执行了")
    return
}
type User struct {
    ID uint `gorm:"primaryKey;autoincrement"`
    BaseModel BaseModel
    Name string
    UUID uuid.UUID
    Role string
}
 
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
    u.UUID = uuid.NewV4()
 
    if u.Role == "admin" {
        fmt.Println("执行失败了")
        return errors.New("invalid role")
    }
    return
}<br><br><br>// 关联创建<br>db.Create(&User{<br>   Name: "马亚南",<br>   BaseModel: BaseModel{Age: 29, Address: "河北"},<br>})

  INSERT INTO `base_models` (`age`,`address`,`user_id`) VALUES (9,'保定',2) ON DUPLICATE KEY UPDATE `user_id`=VALUES(`user_id`)

  INSERT INTO `users` (`name`,`uuid`,`role`) VALUES ('哈哈','a060b60a-1e1c-45b5-a23a-109d04694cba','')

您也可以通过 Select、 Omit 跳过关联保存,例如:

1
2
3
4
5
db.Omit("BaseModel").Create(&User{
    Name: "嘿嘿",
    Role: "admin2",
    BaseModel: BaseModel{Age: 19, Address: "保定2"},
})

  跳过所有关联

1
db.Omit(clause.Associations).Create(&user)

  

8.  默认值

  插入记录到数据库时,默认值会被用于填充值为零值的字段。

注意 像 0''false 等零值,不会将这些字段定义的默认值保存到数据库。您需要使用指针类型或 Scanner/Valuer 来避免这个问题,例如:

1
2
3
4
5
6
7
8
9
type User struct {
    ID int `gorm:"primaryKey;autoIncrement"`
    Name sql.NullString `gorm:"default:'隔壁老王'"`
    Age *uint8 `gorm:"default:55"`
}
 
 
// 带默认值的插入零值
db.Create(&User{Name: sql.NullString{"", true}, Age: new(uint8)})

  

9.  Upsert 及冲突

  在插入冲突时,什么都不做

1
2
ret := db.Clauses(clause.OnConflict{DoNothing: true}).Create(&User{ID: 4, Name: sql.NullString{"你好啊", true}})
fmt.Println(ret.RowsAffected)

  

 

posted @   专职  阅读(216)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示