1. 创建操作
db.Create()
- 创建单条记录
user := User{Name: "Suta", Birthday: time.Now()}
result := db.Create(&user) // 通过数据的指针来创建
返回的result是一个gorm.DB对象,后续文章我们会详细讲解这个对象,这里我们只需要知道他会携带一些我们连接数据库执行SQL需要的信息以及执行之后返回的信息就足够了。
另外,db.Create()会为&user回填主键的值。
- 批量插入
可以借助一个切片实现批量插入的操作:
var users = []User{
{Name: "suta1"},
{Name: "suta2"},
{Name: "suta3"}
}
db.Create(&users)
- 借助 map 创建
db.Model(&User{}).Create(
[]map[string]interface{}{
{"Name": "suta1", "Age": 18},
{"Name": "suta2", "Age": 20},
})
db.Select() / db.Omit()
db.Select()与db.Omit()都可以配合db.Create()使用:
db.Select()是指定需要更新的列db.Omit()是指定不需要更新的列
db.Select("Name", "Age", "CreatedAt").Create(&user)
db.Omit("Name", "Age", "CreatedAt").Create(&user)
db.Model()
可以通过db.Model()方法制定Model结构,方便直接关联数据库表:
db.Model(&User{}).
Create(map[string]interface{}{ "Name": "suta", "Age": 18, })
db.Clauses()
可以通过db.Clauses()配置增加操作导致冲突时的解决策略:
db.Clauses(clause.Locking{Strength: "UPDATE"}).Find(&users)
2. 查询操作
db.First() / db.Take() / db.Last()
db.First() db.Take() db.Last()均为单条查询语句:
db.First()查询第一条db.Take()查询随机的一条db.Last()查询最后一条
// 获取第一条记录(主键升序)
db.First(&user)
// SELECT * FROM users ORDER BY id LIMIT 1;
// 获取一条记录,没有指定排序字段
db.Take(&user)
// SELECT * FROM users LIMIT 1;
// 获取最后一条记录(主键降序)
db.Last(&user)
// SELECT * FROM users ORDER BY id DESC LIMIT 1;
db.Table()
提供类似于SQL中的FROM操作,但是需要注意,与db.First() db.Last()配合时,需要使用db.Model(),因为db.First() db.Last()需要对主键进行排序:
var user User
// 可以
result := map[string]interface{}{}
db.Model(&User{}).First(&result)
// SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1
// 不行
result := map[string]interface{}{}
db.Table("users").First(&result)
db.Find()
db.Find()可以检索所有记录:
result := db.Find(&users)
// SELECT * FROM users;
db.Where().Or()
相当于SQL中的条件查询
db.Not()
相当于SQL中的NOT
db.Order()
db.Order("age desc, name").Find(&users)
// SELECT * FROM users ORDER BY age desc, name;
// 多个 order
db.Order("age desc").Order("name").Find(&users)
// SELECT * FROM users ORDER BY age desc, name;
db.Limit().Offset()
db.Limit() db.Offset()两个方法是分页查询:
db.Limit()是限制页的容量db.Offset()是规定跳过的数据量
db.Limit(10).Offset(5).Find(&users)
// SELECT * FROM users OFFSET 5 LIMIT 10;
db.Group().Having()
实现分组查询:
db.Model(&User{})
.Select("name, sum(age) as total")
.Where("name LIKE ?", "group%")
.Group("name")
.First(&result)
// SELECT name, sum(age) as total
// FROM `users`
// WHERE name
// LIKE "group%"
// GROUP BY `name`
db.Scan() / db.Rows()
返回查询结果:
db.Scan(&ptr)将结果保存到&ptrdb.Rows()返回一个*sql.Row,可以通过.Next()遍历
type Result struct {
Name string
Age int
}
var result Result
db.Table("users")
.Select("name", "age")
.Where("name = ?", "Antonio")
.Scan(&result)
rows, err := db.Table("users").Select("users.name, emails.email").Rows()
for rows.Next() { ... }
3. 更新操作
db.Save() / db.Update() / dp.Updates()
db.Save()会保存所有的字段,即使字段是零值db.Update()只会更新非零值的字段db.Updates()只会更新非零值的字段
db.Save(&user{Name: suta, Age: 00})
db.Model(&User{}).Where("active = ?", true).Update("name", "hello")
// UPDATE users
// SET name='hello', updated_at='2013-11-17 21:34:10'
// WHERE active=true;
dp.UpdateColume()
使用SQL表达式更新列:
db.Model(&product).UpdateColumn("quantity", gorm.Expr("quantity - ?", 1))
// UPDATE "products" SET "quantity" = quantity - 1 WHERE "id" = 3;
4. 删除操作
db.Delete()
如果在没有任何条件的情况下执行批量删除,GORM 不会执行该操作,并返回 ErrMissingWhereClause 错误
db.Where("email LIKE ?", "%jinzhu%").Delete(Email{})
// DELETE from emails where email LIKE "%jinzhu%";
db.Delete(&User{}).Error // gorm.ErrMissingWhereClause
db.Where("1 = 1").Delete(&User{})
// DELETE FROM `users` WHERE 1=1
软删除
如果您的模型包含了一个 gorm.deletedat 字段(gorm.Model 已经包含了该字段),它将自动获得软删除的能力!
拥有软删除能力的模型调用 Delete 时,记录不会被从数据库中真正删除。但 GORM 会将 DeletedAt 置为当前时间, 并且你不能再通过正常的查询方法找到该记录。
可以使用 db.Unscoped() 找到被软删除的记录。
db.Unscoped().Where("age = 20").Find(&users)
// SELECT * FROM users WHERE age = 20;
也可以使用 Unscoped 永久删除匹配的记录.
db.Unscoped().Delete(&order)
// DELETE FROM orders WHERE id=10;
本文正在参加技术专题18期-聊聊Go语言框架