这是我参与「第五届青训营 」笔记创作活动的第5天
Day5
Gorm
Gorm是一个已经迭代了十年+的功能强大的ORM框架,在字节内部被广泛使用
type Product struct{ // Gorm model
code string
price uint
}
func (p Product) TableName() string { //为model定义表明
return "product"
}
db, err := gorm.Open()
db.Create(&Product(Code: "042", Price: 100)) //创建数据
var product Product
db.First(&product, 11) //查询数据
db.First(&product, "code = ?", "042")
db.Model(&product).Update("Price", 200) //更新数据
db.Model(&product).Updates(Product{Code: "F42", Price: 200})
db.Model(&product).Updates(map[string]interface{}{"Code": "F42", "Price": 200})
通过使用 ‘gorm: "primarykry"’定义主键,同时可以使用gorm tag定义列名。
gorm是链式调用,因此使用create创建一条数据会返回一个对象。通过返回对象的Error方法可以返回创建的error。
多条数据创建插入可以使用如下代码
products := []*Product{{Code: "041"}, {Code: "890"}}
唯一主键发生冲突,可以使用clause.OnConfilct处理数据冲突。加上参数DoNoting:true,会不处理冲突并插入数据。
通过default tag可以为结构体字段设置默认值。
first查询一条数据,如果查询不到第一条数据会返回一个error,如果不熟悉会出现问题,因此通常使用find进行数据查询。
find如果没有获取数据会返回空数组。具体代码如下:
users := make([]*User, 0)
result := db.Where("age > 10").Find(&users)
使用结构体作为条件查询时,GORM只会查询非零值字段,这意味着如果你的字段值为0,“”,false或者其他零值,该字段不会用于构建查询条件,可以使用Map来构建查询条件。
db.Model(&User{ID: 111}).Where("age > ?", 10).Update("name", "hello")
//Model只是为了设置表名,并无其他意义,如果不设置会出错
//如果没有where会根据结构体字段值更新
使用struct更新时,只会更新非零值,如果需要更新零值可以使用Map更新或者使用select选择字段。
gorm提供gorm.DeletedAt用于帮助用户实现软删,拥有软删能力的Model调用Delete时,记录不会从数据库中真正被删除,但gorm会将DeletedAt设置会当前时间,并且你不能再通过正常查询方法查到该记录。但能使用Unscoped查询到软删数据。 Gorm提供了Begin、Commit、Rollback用于使用事务。
Gorm提供了Transaction方法用于自动提交事务,避免用户漏写Commit、Rollback。
Gorm提供了CURD的Hook能力,Hook是在创建、查询、更新、删除等操作之前之后自动调用的函数/
如果任何Hook返回错误,Gorm将停止后续操作并回滚事务。