Gorm|青训营笔记

74 阅读2分钟

这是我参与「第五届青训营 」笔记创作活动的第5天

Gorm

迭代10年+的功能强大的ORM框架

使用

开始
//首先定义结构体
type Product struct{
    Code string `gorm:"column:code"`
    Price uint  `gorm:"column:price"`
}
​
//实现TableName方法返回表名即可
func(p Product)TableName()string {
    return "product"
}
处理数据冲突
//以不处理为例
p :=&Product{Code:"D42",ID:1}
db.Clauses{clause.OnConflict{DoNothing:true}.Create(&p)}
使用默认值
//通过default标签
type User struct{
    Id int64
    Name string `gorm:"default:luc"`
    Age int64   `gorm:"default:18"`
}
查询数据
//查询一条数据
u:=&User{}
db.First(u)
//查询多条数据
users:=make([]*User,0)
db.Where("name =?","jinzhu").Find(&useres)
​
db.Where(map[string]interface{}{"Name":"jinzhu","Age":18}).Find(users)

注意:

  • 使用first时,需要注意查询不到数据会返回ErrRecordNotFound
  • 使用Find查询多条数据,查询不到不会返回错误
  • 使用结构体作为条件查询,Gorm只会查询非零字段,所以应该使用map来进行查询
更新数据
//条件更新单个列
db.Model(&User{ID:111}).Where("age > ?",18).Update("name","hello")
​
//更新多个列
db.Model(&User{ID:111}).Updates(User{Name:"hello",Age:18})
​
//根据map更新属性
db.Model(&User{ID:111}).Updates(map[string]interface{}{"name":"hello","Age":18})
​
//更新选定字段
db.Model(&User{ID:111}).Select("name").Updates(map[string]interface{}{"name":"hello","age":18})
​
//SQL表达式更新
db.Model(&User{ID:111}).Update("age",gorm.Expr("age*?+?",2,100))
删除数据
//物理删除
db.Delete(&User{},10)                                   //删除id为10的记录(主键)
db.Delete(&User{}, "10")                                //删除id为10的记录(主键)
db.Delete(&User{}, []int[1,2,3})                        //删除id为1,2,3的记录(主键)
db.Delete(&User{}, "name like ?","%jin%")               //删除名字含jin的记录
db.Where("name like ?","%jinzhu%").Delete(&User{})      //删除名字含jin的记录//软删除
//gorm提供了gorm.DeleteAt帮助用户实现软删除
//软删除只会把DeleteAt置为当前时间,并且无法通过正常方法查询到数据
//使用Unscoped可以查询到被软删的数据
事务
tx:=db.Begin() //开始事务
//执行db操作,用tx替换db
if err:= tx.Create(&User{Name:"name"}).Error;err!=nil{
    tx.RollBack()
    return
}
if err = tx.Create(&User{Name:"name1"}).Error;err!=nil{
    tx.Rollback()
    return
}
//提交事务
tx.Commit()
​
//Transaction自动提交事务
if err := db.Transaction(func(tx *gorm.DB)error{
    if err=tx.Create(&User{Name:"name"}).Error;err1=nil{
        return err
    }
    if err=tx.Create(&User{name:"name1"}).Error;err!=nil{
        tx.Rollback()
        return err
    }
    return nil
}); err!=nil{
    return
}
Hook

Hook是在创建、查询、更新、删除等操作之前、之后自动调用的函数

如果任何Hook返回错误,GORM将停止后续的操作并回滚事务

func (u *User)BeforeCreate(tx *gorm.DB)(err error){
    if u.Age < 0{
        return errors.New("can not save invalid data")
    }
    return
}
性能提高
  • 对于写操作,为了确保数据的完整性,GORM将其封装在事务内运行,但这会降低性能,可以用SkipDefaultTransaction关闭默认事务
  • 使用PrepareStmt缓存预编译语句可以提高后续调用速度
db,err:=gorm.Open(mysql.Open(dsn),
    &gorm.Config{
        SkipDefaultTransaction: true,
        PrepareStmt:            true,
    })  
生态

uTools_1674218762739