这是我参与「第五届青训营 」伴学笔记创作活动的第3天。 今天学习了Go的三个开发框架
- ORM框架——GORM
- RPC框架——Kitex
- Web框架——Hertz 并在此基础上看了一个简单的笔记项目实现
GORM框架
1.创建连接
通过gorm.Open(mysql.Open(), &gorm.Config{})来创建数据库连接,返回一个db操作对象以及err
2.Model
GORM中Model有默认的一些约定,比如
- 如果一个字段名为ID,会被默认当作主键
- 表名默认为结构体的蛇形复数
- 如果存在CreatedAt、UpdatedAt将会自动追踪并更新时间
当然可以通过自定义配置来修改这些默认配置,GORM对Model的配置是采用Golang的Tag标签,比如想修改字段主键,可以在其字段后添上gorm:"primaryKey" 标签
更改配置表名:
再比如实现TableName函数,就能更改表名。
动态配置表名:
如果想实现动态表名,需要使用Scope函数db.Scope(DynamicTableName(user)).Create(&user),其中DynamicTableName()就是自定义动态表名的函数
声明临时表名:
也可以通过db.Table("tableName").where()来指定表名
结构体嵌入:
- 匿名字段会自动嵌入
- 非匿名字段需要在字段后面跟上
gorm:"embedded"标签可以将对象拆分并嵌入结构体中
3.CRUD
Create
通过db.Create(对象)来创建,可以在前面使用Select或者Omit函数
- Select()挑选要插入的字段
- Omit()除去要插入的字段
db.Select("code", "price").Create(&product)
批量插入: 可以直接Create()操作slice进行插入,也可以通过CreateInBatches()函数指定一次插入的数量
var user = []user{{Name:"Lin"}, {Name:"Ye"}, {Name:"Shi"},}
db.Create(&user)
db.CreateInBatches(&user, 100)//指定每次插入的数量
配置CreateBatchSize的值会改变所有与Insert有关的操作
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{ CreateBatchSize: 1000,})
Retrieve
查询单个对象
First()按主键升序LIMIT1Take()无排序LIMIT1Last()按主键降序LIMIT1
*注意: *如果没有找到记录会返回ErrRecordNotFound错误,如果想避免这个错误,就使用Find查询
db.Limit(1).Find(&user)
查询多个对象
使用Find
注意: 如果使用结构作为条件查询的时候,一些默认字段比如0、false等不会被用于检索,这种情况要使用Map充当查询条件
Update
save()会保存所有字段,即使是默认值
如果没有使用where函数,GORM不会执行本次操作,因为是全局更新,它会报ErrMissingWhereClause错误
所以必须要携带条件或者配置AllowGlobalUpdate模式
db.Session(&gorm.Session{AllowGlobalUpdate: true}).Model(&User{}).Update("name", "jinzhu")
Delete
没有携带where的删除,要指定或存在主键字段,否则会触发批量删除,将所有匹配的记录都删除
db.Delete(&user)
如果没有任何条件的删除,GORM不会执行,会返回ErrMissingWhereClause错误,需要带上条件或者启用AllowGlobalUpdate模式
db.Delete(&User{})
逻辑删除:
引入Deleted gorm.DeletedAt字段,或者 gorm.Model字段(其包含了DeletedAt)就会执行逻辑删除,并且通过正常查询查询不到
如果需要查找逻辑删除的数据,需要通过Unscope().Find()
Hook
GORM对INSERT、UPDATE、DELETE等一些操作都可以定义Hook,让其在执行前后都能切面做一些额外的操作
事务
通过db.Begin()来开启事务,并且获得一个事务对象tx,接下来的操作都是通过tx来执行的
回滚: tx.Rollback()
提交: tx.Commit()
为了避免漏写Rollback和Commit方法,GORM提供了Transaction方法,会自动提交和回滚事务
db.Transaction(func(tx *gorm.DB) error {
if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
return err
}
if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
return err
}
return nil
})
禁用默认事务
通过设置SkipDefaultTransaction : true,将会禁用默认事务,性能大概提升30%