前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Gorm 高级查询

Gorm 高级查询

原创
作者头像
王小明_HIT
发布2022-02-13 14:43:06
2.3K0
发布2022-02-13 14:43:06
举报
文章被收录于专栏:程序员奇点程序员奇点

前言

越高级,越复杂的查询,也同时意味着高耗,但是平时有一些数据少,但是业务复杂的场景,可以使用下。 这里主要说明的是 go 中使用 gorm 进务查询。

gorm import 依赖

代码语言:javascript
复制
 "database/sql"
 "fmt"
 "github.com/jinzhu/gorm"
 _ "github.com/jinzhu/gorm/dialects/mysql"

将查询结果放到一个 struct 中

代码语言:javascript
复制
// 根据主键查询第一条记录
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.Find(&users)
//// SELECT * FROM users;

// 查询指定的某条记录(仅当主键为整型时可用)
db.First(&user, 10)
//// SELECT * FROM users WHERE id = 10;

查询条件是map 或者 struct 查询

有时候代码是可需要映射到一个 map 结构, 不需要映射到一个 结构体中,可以写成如下:

for update

在涉及并发的场景,往往需要加锁互斥,和 Java 类似, Go 中也有加行锁的方式,加 for update 即可。

一般写法如下:

代码语言:javascript
复制
// 为查询 SQL 添加额外的 SQL 操作
db.Set("gorm:query_option", "FOR UPDATE").First(&user, 10)
//// SELECT * FROM users WHERE id = 10 FOR UPDATE;

示例代码:

代码语言:javascript
复制
err := db.Model(&XXX{}).Set("gorm:query_option", "FOR UPDATE").Where("XXX=?", XXX).First(&XXX).Error
 if err != nil {
  if err == gorm.ErrRecordNotFound {
   logs.Warn("xxx")
   return nil, nil
  }
  logs.Error("XXX")
 }

Count 查询

有时候,我们需要进行简单的数据统计, 比如查询到结果有多少行,

代码语言:javascript
复制
var count int64
db.Model(&User{}).Where("name = ?","jinzhu").Or("name = ?","jinzhu 2").Count(&count)
// SELECT count(*) FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2'
db.Model(&User{}).Where("name = ?","jinzhu").Count(&count)
// SELECT count(*) FROM users WHERE name = 'jinzhu'; (count)
分组计数

有时候也需要分组统计行数

代码语言:javascript
复制
// 分组计数
users :=[]User{
{Name:"name1"},
{Name:"name2"},
{Name:"name3"},
{Name:"name3"},
}
DB.Model(&User{}).Group("name").Count(&count)
count // => 3
去重统计
代码语言:javascript
复制
// 去重计数
DB.Model(&User{}).Distinct("name").Count(&count)
// SELECT COUNT(DISTINCT(`name`)) FROM `users`

Group & Having

有时候我们会使用到数据统计的功能, 比如根据数据库字段 batch_no 进行分组,然后统计总金额,总笔数。

分组查询统计一般的写法如下:

代码语言:javascript
复制
db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Having("sum(amount) > ?", 100).Scan(&results)

代码示例:

代码语言:javascript
复制
type Sum struct {
 BatchNo      string `gorm:"column:batch_no" json:"batch_no"`
 TotalCounts  int64  `gorm:"column:total_counts" json:"total_counts"`
 TotalAmounts int64  `gorm:"column:total_amounts" json:"total_amounts"`
}


var result []*Sum
 db := db.Model(&Voucher{}).Select("batch_no, count(1) as totalCounts, sum(amount) as totalAmounts")
 status := []string{10,20,40}

 db = db.Where("no >= ?", startVoucherNo)
 db = db.Where("no <= ?", endVoucherNo)
 db = db.Where("batch_no IN ?", batchNos)
 db = db.Where("status IN ?", status)

 if shardingKey >= 0 {
  db = db.Where("sharding_key = ", shardingKey)
 }

 db = db.Group("batch_no")
 err := db.Scan(&result).Error
 if err != nil {
  if err == gorm.ErrRecordNotFound {
   logs.CtxWarn("xxx")
   return nil, nil
  }
  logs.CtxError(ctx, "xxx", err)
 }

Join 查询

一般来说,很少使用关联查询,但是如果要使用关联查询,可以如下:

代码语言:javascript
复制
db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&results)

// 多连接及参数
db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Joins("JOIN credit_cards ON credit_cards.user_id = users.id").Where("credit_cards.number = ?", "411111111111").Find(&user)

查询指定函数

Scopes允许你指定常用的查询,可以在调用方法时引用这些查询, 也就是说,可以在查询中使用函数。

举个例子:

代码语言:javascript
复制
func AmountGreaterThan1000(db *gorm.DB)*gorm.DB {
return db.Where("amount > ?",1000)
}

func PaidWithCreditCard(db *gorm.DB)*gorm.DB {
return db.Where("pay_mode_sign = ?","C")
}
func PaidWithCod(db *gorm.DB)*gorm.DB {
return db.Where("pay_mode_sign = ?","C")
}

db.Scopes(AmountGreaterThan1000,PaidWithCreditCard).Find(&orders)
// 查找所有金额大于 1000 的信用卡订单


db.Scopes(AmountGreaterThan1000,PaidWithCod).Find(&orders)
// 查找所有金额大于 1000 的货到付款订单
参考资料
  • https://www.cnblogs.com/zisefeizhu/p/12788060.html
  • https://gorm.io/zh_CN/docs/advanced_query.html
  • https://www.bookstack.cn/read/gorm-2.0/docs-advanced_query.md#4abzu1

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • gorm import 依赖
  • 将查询结果放到一个 struct 中
  • 查询条件是map 或者 struct 查询
  • for update
  • Count 查询
    • 分组计数
      • 去重统计
      • Group & Having
      • Join 查询
      • 查询指定函数
        • 参考资料
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档