Gorm 高级查询

简介: Gorm 高级查询

前言


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

gorm import 依赖


"database/sql"
 "fmt"
 "github.com/jinzhu/gorm"
 _ "github.com/jinzhu/gorm/dialects/mysql"

将查询结果放到一个 struct 中


// 根据主键查询第一条记录
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 即可。

一般写法如下:


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

示例代码:


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 查询


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


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)
分组计数


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


// 分组计数
users :=[]User{
{Name:"name1"},
{Name:"name2"},
{Name:"name3"},
{Name:"name3"},
}
DB.Model(&User{}).Group("name").Count(&count)
count // => 3
去重统计


// 去重计数
DB.Model(&User{}).Distinct("name").Count(&count)
// SELECT COUNT(DISTINCT(`name`)) FROM `users`

Group & Having


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

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


db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Having("sum(amount) > ?", 100).Scan(&results)

代码示例:


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 查询


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


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允许你指定常用的查询,可以在调用方法时引用这些查询, 也就是说,可以在查询中使用函数。

举个例子:


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 的货到付款订单
相关文章
|
消息中间件 负载均衡 监控
【ZMQ PUB模式指南】深入探究ZeroMQ的PUB-SUB模式:C++编程实践、底层原理与最佳实践
【ZMQ PUB模式指南】深入探究ZeroMQ的PUB-SUB模式:C++编程实践、底层原理与最佳实践
3951 1
|
Linux
【Linux 系统编程】wait函数详解
【Linux 系统编程】wait函数详解
488 0
|
SQL 关系型数据库 MySQL
GORM V2 安装和连接 MySQL
GORM V2 安装和连接 MySQL
1083 0
|
11月前
|
Java 关系型数据库 数据库连接
简单易懂的 MyBatis 分库分表方案
本文介绍了一种基于 MyBatis 框架的数据库分库分表方案——shardino。不同于复杂插件方式,该方案通过客户端代码包装实现简便易懂的操作,显式处理分库分表逻辑,确保开发者清晰了解数据分布。项目地址:[https://github.com/pyloque/shardino](https://github.com/pyloque/shardino)。方案中,帖子表按 userId 字段 hash 分为 64 张表,平均分配到多个主从库中,配置文件管理 MySQL 组对象,支持读写分离和权重随机选择从库。代码示例展示了如何计算 partition number 并进行具体操作。
349 22
简单易懂的 MyBatis 分库分表方案
|
11月前
|
机器学习/深度学习 人工智能 云计算
与阿里合作项目荣获2024年度教育部产学合作协同育人项目优秀案例
该项目强调利用阿里云计算有限公司的低代码开发平台和算力资源,开发创新性的教学案例,以支持机器学习和深度学习等前沿技术课程的教学和实验。项目部分成果纳入了即将出版的《深度学习实战案例》教材中,该教材由人民邮电出版社出版。
572 10
|
消息中间件 监控 Kafka
AutoMQ 生态集成 Redpanda Console
今天分享的内容是如何通过 Redpanda Console对 AutoMQ 集群状态进行监控,以提高系统的可维护性和稳定性。
266 2
AutoMQ 生态集成 Redpanda Console
|
数据采集 存储 数据挖掘
如何利用Python进行网页数据抓取
本文将详细介绍如何使用Python进行网页数据抓取。首先,我们将了解什么是网络爬虫以及其基本原理。然后,逐步讲解如何使用Python的requests库和BeautifulSoup库来抓取和解析网页数据。最后,通过实例展示如何实际应用这些技术来获取所需的数据并进行简单的数据处理。希望通过这篇文章,读者能够掌握基本的网页数据抓取技巧,并能在实际应用中灵活运用。
1104 1
|
Web App开发 负载均衡 API
ZLMediakit-集群部署
ZLMediakit-集群部署
1427 0
|
存储 NoSQL 关系型数据库
向量数据库有什么用?
向量数据库是一种特殊类型的数据库,它可以将非结构化数据映射为高维向量,并计算数据之间的相似性。它可以用于查找相似的数据、推荐系统、异常检测和临时存储等应用。目前市场上有一些专门的向量数据库产品,同时也可以使用已有的数据库产品来构建向量数据库。向量数据库的发展前景还不确定,但它已经成为热门技术,并吸引了大量的投资。
|
算法 Python
NumPy 高级教程——性能优化
NumPy 高级教程——性能优化 【1月更文挑战第2篇】
704 0