如何利用GORM 在进行数据查询的同时获得总行数。

JinxLeader 2017-04-23 10:49:42
我现在采用如下所示的方法,利用gorm进行数据查询,请问在使用limit()的前提下如何获得所查数据的总行数?如 sql_calc_found_rows ?

webdb.Select(queryDBInfo.QueryInfos).Where(queryDBInfo.QueryCriteria).Order(queryDBInfo.SortCriteria).Offset(queryDBInfo.Offset).Limit(queryDBInfo.Count).Find(&find)

...全文
7819 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
ckx0709 2021-03-30
  • 打赏
  • 举报
回复 2
引用 1 楼 SadInSilence 的回复:
可以这样:db.Table(表名).Where(条件).Count(&totalSize).Sort(排序).Offset(offset).Limit(limit).Find(values) 原理是先按条件count,再查询分页。亲测,有效!
values的结构体是什么贴出来看看。
哈哈gogo 2020-09-14
  • 打赏
  • 举报
回复
没必要的,我都直接在底层处理error不再向上分发
qybao 2020-08-30
  • 打赏
  • 举报
回复
单纯从语句出发也是有问题的。这里主要针对你where语句正确合在一起不会出问题的说法而延伸的。sql语句正确不代表sql就能正常执行,数据库的状态随时在变化,你能百分百保证每次sql都成功?正因如此,才要在考虑程序的健壮性。两条sql分别判断,目的就是防止如果第一条失败,就没必要执行第二条了。按你的思路,如果第一条select失败,第二条select count却成功了(合在一起最终结果算成功),你是返回结果还是不返回?返回结果就会造成总件数对了,而详细一览为空,这不是给程序带来隐患bug吗? 如果业务需要的数据要完全保证一致,select加锁又有何不可,锁行甚至锁表都可以,锁的实现多了去了。
Nihility/ 2020-08-29
  • 打赏
  • 举报
回复
引用 9 楼 qybao 的回复:
[quote=引用 8 楼 Nihility/ 的回复:][quote=引用 6 楼 qybao 的回复:]因为gorm的find和count是分别发行sql的,你可以打印sql的log,会发行两条sql,一条select *,一条select count(*)。因为是两条sql,所以就有可能一条成功,一条失败,或者两条都失败。如果第一条失败了,就没必要执行第二条了,所以分开做个判断比较合理。
如果where条件正确的情况下,这句合在一起写是不会出问题的[/quote]那只能说你把用例想得太简单了。发行两条sql,就注定有时间差(哪怕多线程执行也一样有时间差)。如果你主观认定时间差不会影响,那大家还这么努力想办法解决事务和并发问题干毛啊?[/quote] 我前边已经说了,业务需要拆开也没问题。单纯从语句上出发,我倒不认为我说的没问题,不过你要延伸了说,如你说的并发情况下,那只能分两次发的情况,怎么就可以保证第一次和第二次的结果就是一样呢?难道select的还能加锁?请指教一下,多谢!
qybao 2020-08-29
  • 打赏
  • 举报
回复
引用 8 楼 Nihility/ 的回复:
[quote=引用 6 楼 qybao 的回复:]因为gorm的find和count是分别发行sql的,你可以打印sql的log,会发行两条sql,一条select *,一条select count(*)。因为是两条sql,所以就有可能一条成功,一条失败,或者两条都失败。如果第一条失败了,就没必要执行第二条了,所以分开做个判断比较合理。
如果where条件正确的情况下,这句合在一起写是不会出问题的[/quote]那只能说你把用例想得太简单了。发行两条sql,就注定有时间差(哪怕多线程执行也一样有时间差)。如果你主观认定时间差不会影响,那大家还这么努力想办法解决事务和并发问题干毛啊?
Nihility/ 2020-08-29
  • 打赏
  • 举报
回复
引用 6 楼 qybao 的回复:
因为gorm的find和count是分别发行sql的,你可以打印sql的log,会发行两条sql,一条select *,一条select count(*)。因为是两条sql,所以就有可能一条成功,一条失败,或者两条都失败。如果第一条失败了,就没必要执行第二条了,所以分开做个判断比较合理。
如果where条件正确的情况下,这句合在一起写是不会出问题的
Nihility/ 2020-08-29
  • 打赏
  • 举报
回复
引用 6 楼 qybao 的回复:
因为gorm的find和count是分别发行sql的,你可以打印sql的log,会发行两条sql,一条select *,一条select count(*)。因为是两条sql,所以就有可能一条成功,一条失败,或者两条都失败。如果第一条失败了,就没必要执行第二条了,所以分开做个判断比较合理。
那我补充点,count的select后边跟的是count(*),到底是不是或者什么情况是count(*)还是其他的,我不能确定;如果where条件正确的情况下,这句是不会出问题的,但是如果没有分开,而select里写的列是有可能出错的,所以不一定会同时成功。 以上我还是觉得多余,如果这样的问题都能过测试,那谈论这个有什么卵用?所以最终,我觉得合并在一起也是没问题的。
qybao 2020-07-30
  • 打赏
  • 举报
回复
因为gorm的find和count是分别发行sql的,你可以打印sql的log,会发行两条sql,一条select *,一条select count(*)。因为是两条sql,所以就有可能一条成功,一条失败,或者两条都失败。如果第一条失败了,就没必要执行第二条了,所以分开做个判断比较合理。
Nihility/ 2020-07-30
  • 打赏
  • 举报
回复
引用 3 楼 qybao 的回复:
for example tx := db.Where(xxx).Find(&data) if tx.Error == nil { tx = tx.Count(&count) }
引用 2 楼 fwhezfwhez 的回复:
不推荐这样写 两次查询,有两次出错的可能,error要分开处理,不要偷懒 ```go var count int if e:=db.Model(&model).Where("x >?", model.X).Count(&count).Error;e!=nil { handle(e) } if count !=0 { if e:=db.Model(&model).Where("x >?", model.X).Find(&models).Error;e!=nil { handle(e) } }
楼上说的"两次查询,有两次出错的可能" 就要分开查? 不太懂 为什么要分开! 查count和查数据任何一个出错出现error 都可以根据业务考虑是不是暂停流程,个人觉得没道理一定要分开,除非是业务流程需要!
学生董格 2020-06-12
  • 打赏
  • 举报
回复
先调用.count(&a) 然后limit().offset().Scan(&b)
fwhezfwhez 2019-09-19
  • 打赏
  • 举报
回复
不推荐这样写

两次查询,有两次出错的可能,error要分开处理,不要偷懒
```go
var count int
if e:=db.Model(&model).Where("x >?", model.X).Count(&count).Error;e!=nil {
handle(e)
}
if count !=0 {
if e:=db.Model(&model).Where("x >?", model.X).Find(&models).Error;e!=nil {
handle(e)
}
}
qybao 2019-09-19
  • 打赏
  • 举报
回复
for example
tx := db.Where(xxx).Find(&data)
if tx.Error == nil {
tx = tx.Count(&count)
}
SadInSilence 2019-05-14
  • 打赏
  • 举报
回复
可以这样:db.Table(表名).Where(条件).Count(&totalSize).Sort(排序).Offset(offset).Limit(limit).Find(values) 原理是先按条件count,再查询分页。亲测,有效!

2,190

社区成员

发帖
与我相关
我的任务
社区描述
go语言学习与交流版
社区管理员
  • go语言社区
  • Freeman Z
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧