Go框架三件套——grom
这是我参与「第五届青训营」伴学笔记创作活动的第5天
介绍:
orm是object relational mapping的缩写,意思就是对象映射关系,一般我们使用的java、python什么的都是面向对象开发,但是数据库一般是关系型,为了保持开发一致的习惯,orm就把编程语言的对象模型和数据库的关系模型建立了映射关系,这样就可以不用直接使用sql而使用对象模型就可以对数据库进行操作了。
GORM 是一个适用于 Go 语言的 ORM 库,遵循 ActiveRecord 模式进行设计。GORM 的功能非常强大,除了基本的基于模型类对数据表进行增删改查之外,还支持定义关联关系、执行数据表迁移、查询链以及很多其他高级特性,并且支持在特定事件发生时(比如插入、更新、删除)触发指定的回调函数(类似 Laravel 框架的模型事件)。
使用
gorm:db操作
约定
- Gorm使用名为ID的字段作为主键
- 使用结构体的蛇形复数作为表名(蛇形复数)
- 字段名的蛇形作为列名
- 使用CreatedAt、UpdatedAt字段作为创建更新时间
连接数据库
dsn := "sqlserver://grom:LoremIpsum86@localhost:9930?database=grom"
db,err := grom.Open(sqlserver.Open(dsn),&grom.Config{})
使用AutoMigrate()函数可以直接根据结构体创建数据库表,其名称可以指定,默认是结构体名的蛇形复数,其默认主键为ID。
1.创建数据
- 创建一条
p:= &Product{Code:"042"}
res:=db.Create(p)
fmt.Println(res.Error)
fmt.Println(p.ID)
- 创建多条
products:=[]*Product{{Code:"041"},{Code:"042"},{Code:"043"}}
res = db.Create(products)
- 唯一索引冲突
p:=&product{Code:"D42",ID:1}
db.Clauses(clause.OnConflict{DoNothing:true}).Create(&p)
- 为字段定义默认值
type User struct{
ID int64
Name string `grom:"default:galeone"`
Age int64 `grom:"default:18"`
}
2.查询数据
- 获取一条数据
u := &User
db.First(u)//select * from users ORDER By id LIMIT 1;
- 查询多条数据
users:=make([]*User,0)
result := db.Where("age > 18").Find(&users)//select * from users where age > 18;
fmt.Println(result.RowsAffected)//lne(users)
fmt.Println(result.Error)
//IN:select * from users where name in ("jinzhu","jinzhu 2");
db.Where("name IN ?",[]string{"jinzhu","jinzhu 2"}).Find(&users)
//LIKE:select * from users where name like "%jin%";
db.Where("name like ?","%jin%").Find(&users)
//AND:select * from users where name = "jinzhu" and age >= 22
db.Where("name = ? AND age >= ?","jinzhu","22").Find(&users)
//select * from users where name = "jinzhu"用结构体查询时,"零值不会被构建查询条件"
db.Where(&user{Name:"jinzhu",Age:0}).Find(&users)
//select * from users where name = "jinzhu" and age = 0;
d.Where(map[string]interface{}{"Name":"jinzhu","Age":0}).Find(&users)
- First和Find first查询不到会返回ErrRecordNotFound,Find查询不到不会返回错误。
3.更新数据
- 更新单个列 Model根据参数结构体返回表名(tablename接口或蛇形复数)
//update users set name = "hello",update_at'2013-11-17 21:34:10' where age > 18;
db.Model(&user{ID:111}).Where("age > ?",18).update("name","hello")
- 更新多个列
//update users set name = "hello",age = 18,actived=false,update_at = '2013-11-17 21:34:10' where id =111;
db.Model(&user{ID:111}).updates(User{Name:"hello",Age:18})
- 更新选定字段
//update users set name = "hello" where id = 111;
db.Model(&user{ID:111}).Select("name").Updates(map[string]interface{}{"name":"hello","age":18,"actived":fales})
- 表达式更新
//update “products”set "price" = price*2+100,"updates_at" = "2013-11-17 21:34:10" where "id" = 3;
db.Model(&User{ID:111}).Update("age",grom.Expr("age * ? + ?",2,100))
4.删除数据
- 物理删除
db.Delete(&user{},10)//delete from users where id = 10;
db.Delect(&user{},"10")//delete from user where id = 10;
db.Delect(&user{},[]int{1,2,3})//delete from user where id in (1,2,3);
db.Where("name like ?",%jinzhu%).Delete(User{})//delete from user where name like %jinzhu%;
db.Delect(user{},"email like ?","%jinzhu%")//delete from user where name like %jinzhu%;
- 软删除 提供grom.DeletedAt软删除,调用后会将DeleteAt置为当前时间,并且不能通过正常查询方法找到该记录。需要使用Unscoped查询被软删除数据。
//在结构体中加入grom.DeletedAt字段
type User struct{
ID int64
Name string `grom:"default:galeone"`
Age int64 `grom:"default:18"`
Deleted grom.DeletedAt
}
//查询被软删除数据
db.Unscoped().Where("age = 20").Fnd(&users)
5.GROM事务——Begin、Commit、Rollback
- Begin
tx:=db.Begin()//开启一个事务,1.固化链接 2执行开启事务的sql语句后返回一个DB(tx)与链接池中的DB(db)不同。
tx.Create()//创建数据
//出错
tx.Rollback()//回滚
tx.Commit()//提交事务
grom提供了Tansaction方法用于自动提交事务,避免漏写Commit、Rollback
if err = db.Transaction(func(tx * grom.DB) error {
if err = tx.Create(&User{Name:"name"}).Error;
err!=nil{
return err
}
if err = tx.Create(&User{Name:"name1"}).Error;
err!=nil{
tx.Rollback()
return err
}
return nil
})
err != nil{
return
}
6.GROM HOOK
type User struct{
ID int64
Name string `grom:"default:galeone"`
Age int64 `grom:"default:18"`
}
type Email struct{
ID int64
Name string
Email string
}
func (u *User) BeforeCreate(tx * grom.DB)(err error){
if u.Age < 0{
return errors.New("Can't save invalid data")
}
return
}
func (u *User)AfterCreate(tx * grom.DB)(err error){
return tx.Create(&Email{ID:u.ID,Email:u.Name+"@***.com"}).error
}
引用
zhuanlan.zhihu.com/p/586396679
cloud.tencent.com/developer/a…