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

182 阅读4分钟

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…