如何通过GORM获取查询结果总条数以实现分页展示
如何通过GORM获取查询结果总条数以实现分页展示
嘿,刚好我之前做分页功能的时候也纠结过这个问题!要实现「显示11-20条,共154条」这种效果,GORM有几种实用的方案,不一定非得写两套重复的查询逻辑,给你捋一捋:
- 方案一:复用查询条件,用Count获取总条数(推荐,兼容性强)
这是最常用也最稳妥的方式,先通过Count方法拿到符合条件的总条数,再执行分页查询。关键是可以复用你的查询条件,避免重复写Where、Joins这些逻辑。
比如你的模型是Product,要查询状态为上架的商品:
// 先构建查询条件,用Model方法复用条件,不直接查询数据 var total int64 query := db.Model(&Product{}).Where("status = ?", 1) // 获取符合条件的总条数 query.Count(&total) // 执行分页查询:从第11条开始,取10条(对应11-20条的展示) var products []Product query.Offset(10).Limit(10).Find(&products)
要是你的查询条件比较复杂(比如有多级Where、Joins、Order),可以把查询条件封装成GORM的Scope,让代码更干净:
// 定义Scope,封装复杂的查询逻辑 func OnSaleScope(db *gorm.DB) *gorm.DB { return db.Where("status = ?", 1).Joins("LEFT JOIN categories ON products.category_id = categories.id").Where("categories.is_active = ?", true) } // 复用Scope获取总条数和分页数据 var total int64 OnSaleScope(db.Model(&Product{})).Count(&total) var products []Product OnSaleScope(db).Offset(10).Limit(10).Find(&products)
这里要提一句:GORM的Count方法会自动忽略Limit和Offset,所以就算你不小心在之前的查询里加了这两个,也不会影响总条数的准确性。
- 方案二:用数据库原生语法一次性获取数据和总条数(适合特定数据库)
如果你的项目用的是MySQL,可以利用SQL_CALC_FOUND_ROWS和FOUND_ROWS()来优化:先查询分页数据的同时让数据库计算总条数,再通过一个简单查询拿到总数,数据库层面会做优化,减少一次复杂查询的开销:
var products []Product // 用SQL_CALC_FOUND_ROWS告诉数据库计算符合条件的总条数 db.Select("SQL_CALC_FOUND_ROWS *").Where("status = ?", 1).Offset(10).Limit(10).Find(&products) // 用FOUND_ROWS()获取刚才计算的总条数 var total int64 db.Raw("SELECT FOUND_ROWS()").Scan(&total)
不过这个方式有局限性:不是所有数据库都支持(比如PostgreSQL就没有这个语法),而且在高并发场景下,可能会因为数据库连接池或事务隔离级别的问题出现总数不准确的情况,所以要根据你的实际场景来选择。
总的来说,如果追求兼容性和代码可读性,方案一绝对是首选;如果是MySQL环境且查询逻辑复杂,想优化数据库交互,可以试试方案二。
备注:内容来源于stack exchange,提问作者Orange Lux
相关产品推荐
相关产品推荐

