Golang Go语言中请教一下 Gorm 的 Count 问题
Golang Go语言中请教一下 Gorm 的 Count 问题
Count 方法这里怎么会多出一个 and 条件,导致结果不正确呢,我代码有问题么?
go 新手 求指点
代码片段
util 中部分定义:
package util
type Result struct {
Code uint json:"code"
Data interface{} json:"data"
}
// NewResult creates a result with Code=0, Msg="", Data=nil.
func NewResult() *Result {
return &Result{
Code: 200,
Data: nil,
}
}
type JobRequestParam struct {
ID []uint form:"id" binding:"required"
OpsID uint form:"ops_id" binding:"required"
RunTime string form:"run_time"
}
查询方法
package service
import (
“OpsSimon/util”
“log”
“sync”
)
// AssetsService 资产对象
type AssetsService struct {
mutex *sync.Mutex
}
// Assets 资产实例
var Assets = &AssetsService{
mutex: &sync.Mutex{},
}
// GetList 列表查询
func (srv *AssetsService) GetList(result interface{}, id []uint) (total int) {
err := db.Where(id).Find(result).Count(&total).Error
if err != nil {
log.Println(err.Error())
}
return total
}
执行
func doJob(c *gin.Context) {
result := util.NewResult()
defer c.JSON( http.StatusOK, result)
var arg util.JobRequestParam
err := c.BindJSON(&arg)
if err != nil {
result.Code = http.StatusBadRequest
result.Data = err.Error()
return
}
log.Println(arg.ID)
log.Println(arg.OpsID)
log.Println("len:", len(arg.ID))
var host model.AssetsHosts
total := service.Assets.GetList(&host, arg.ID)
log.Println("total:", total)
if total != len(arg.ID) {
result.Code = http.StatusNotFound
result.Data = "Some host not found!"
return
}
}
更多关于Golang Go语言中请教一下 Gorm 的 Count 问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
建议提问题的时候简明扼要一点,这里无关的东西太多了。
我的印象中 Find,和 Count 应该分开用吧,你这样想一下查两个值应该有点问题。
开一下 orm 的 log,测试两下不就出来了么。
更多关于Golang Go语言中请教一下 Gorm 的 Count 问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
验证了一下,这么用也是对的,gorm 拆分成两个 sql 语句了。
问题应该在与你的 db 对象,前面已经加了条件了。
红框里的应该是 Where(id)这一句导致的吧
并不行,分开使用一样不行,我是尝试过才来提问的,没有拿来主义
我看官方文档是可以这样用的
db 对象没有加条件,下面的代码片段可以看到,出了 midel 其它相关基本都贴出来了
把 SQL 打印一下,看看。
#6 图里面有,然后我再贴一下多出 and 的那条语句sql<br><br>SELECT count(*) FROM `ops_assets_hosts` WHERE `ops_assets_hosts`.`deleted_at` IS NULL AND `ops_assets_hosts`.`id` = 3 AND ((`ops_assets_hosts`.`id` IN (1,2,3))) <br>
#5 用 goland 帮你 debug 了一下
如果按照你的写法 db.Where(id).Find(result).Count(&total).Error
会产生两次 sql 查询, 就像你日志里面打印的两条一样. Find(result)这个方法本身会 select * from xxx where xxx in xxx
查询一遍结果, 然后当你链式调用到 Count(&total)的时候, 实际上这个时候的 DB 对象本身是含有 Value 了的, Value.ID 是根据你 where 条件的查询得到结果的最后一条的 ID.
没有再深入看 gorm 里面的代码, 我猜里面是有一个循环赋值的过程, 当你用 Count(&total)进行查询的时候, DB 对象已经被 Find(result)循环赋值完, 成为 Find(result)结果的最后一条, 所以会多出来一个 and 条件. 如果你试试把 arg.ID 换成[1,2,3,4,5], 那这个 where 条件应该会变成 and id = 5.
表述的可能不太清楚, 你可以自己试试 debug, 把断点打在 Count 方法的return s.NewScope(s.Value).count(value).db<br>
这一行就可以了~
#8 非常感谢,我去验证了一下,就是你说的这个问题
如果我先 Find 再 Count 必定会多出一个 and id = arg.ID [-1] 的条件出来
我将代码改成下面这样,结果和 sql 语句就是正确的
err := db.Model(result).Where(id).Count(&total).Error
err = db.Where(id).Find(result).Error
#9 哈哈解决问题了就好
#10
官方文档里面说可以像我之前那个用
http://gorm.io/docs/query.html#Count
感觉应该是 gorm 的 bug,我提了个 issues 看看官方杂说
https://github.com/jinzhu/gorm/issues/2647
#11 看文档里面确实是可以这样用, subscribe 了这个 issue 看看开发者怎么说
在Golang中使用Gorm进行数据库操作时,Count
方法是一个非常实用的功能,用于计算符合查询条件的记录数。下面是一些关于如何在Gorm中使用 Count
方法的要点:
-
基本用法:
Count
方法通常用于计算表中的记录数。例如,要计算users
表中的总记录数,可以这样做:var count int64 result := db.Model(&User{}).Count(&count).Error if result != nil { // 处理错误 } fmt.Println("Total users:", count)
-
带条件的计数: 你也可以在
Count
方法中使用条件来限制计数范围。例如,要计算年龄大于30的用户数量,可以这样做:var count int64 result := db.Model(&User{}).Where("age > ?", 30).Count(&count).Error if result != nil { // 处理错误 } fmt.Println("Users older than 30:", count)
-
注意事项:
- 确保传递给
Count
的变量是*int64
类型,因为 Gorm 会将计数结果存储在这个变量中。 - 如果查询过程中出现错误,
Count
方法会返回一个错误对象,记得进行错误处理。 Count
方法不会返回查询结果集,只会返回符合条件的记录数。
- 确保传递给
希望这些信息能帮助你更好地理解和使用Gorm中的 Count
方法。如果有其他问题或需要进一步的帮助,请随时提问。