Go框架三件套 | 青训营笔记

104 阅读2分钟

这是我参与「第五届青训营 」笔记创作活动的第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将停止后续操作并回滚事务。