Golang GORM 搜索条件
Golang GORM search conditions
使用 gorm 和 postgres 在 Golang 中编写网络服务器时,我对以下代码中第二次循环迭代的确切情况产生了误解:
...
for _, t := range tasks {
newDbConn := db.SchoolServerDB.Debug().New()
err = newDbConn.Where("id = ?", t.DayID).First(&day).Error
if err != nil {
return errors.Wrapf(err, "Error query day with id='%v'", t.DayID)
}
...
}
...
第一次迭代调试:
SELECT * FROM "days" WHERE "days"."deleted_at" IS NULL AND ((id = '8')) ORDER BY "days"."id" ASC LIMIT 1
第二次迭代调试:
SELECT * FROM "days" WHERE "days"."deleted_at" IS NULL AND "days"."id" = '8' AND ((id = '38')) ORDER BY "days"."id" ASC LIMIT 1
关键问题是:尽管每次迭代都会创建一个新连接,但为什么会累积搜索条件?根据docs搜索条件每次都要清除。我想得到这样的第二个结果:
SELECT * FROM "days" WHERE "days"."deleted_at" IS NULL AND ((id = '38')) ORDER BY "days"."id" ASC LIMIT 1
感谢任何帮助!
UPD:
db.SchoolServerDb 只是 *gorm.DB 而 Debug() 是它的方法
Table 'days' 由结构日组成:
type Day struct {
gorm.Model
StudentID uint // parent id
Date string `sql:"size:255"`
Tasks []Task // has-many relation
Lessons []Lesson // has-many relation
}
您的搜索条件没有问题。您只需在第二次迭代的查询中提供多个 ID。一个在 Where
中,另一个在 Find
中。
让我写一个像你这样的例子
ids := []int{1, 2}
var org database.Organization
for _, i := range ids {
db, _ := connection.NewPGConnection(info)
db = db.Debug().New()
db.Where("id = ?", i).Find(&org)
}
这里,SQL第一次迭代查询如下:
SELECT * FROM "organizations" WHERE "organizations"."deleted_at" IS NULL AND ((id = '1'))
在第二次迭代中它将是:
SELECT * FROM "organizations" WHERE "organizations"."deleted_at" IS NULL AND "organizations"."id" = '1' AND "organizations"."code" = 'mir' AND ((id = '2'))
为什么?因为,您使用了相同的变量 day 来读取行结果。
第一次,还可以。但是第二次,您的 day 变量中已经有一个 ID。并且您在 Where
中提供了另一个。这就是为什么它的 运行 查询有两个 ID。
You are actually providing two id
, one in where
clause and another in Find
.
更改代码以每次重新声明变量 day。像这样。
ids := []int{1, 2}
for _, i := range ids {
db, _ := connection.NewPGConnection(info)
db = db.Debug().New()
var org database.Organization // <----- move your variable day here
db.Where("id = ?", i).Find(&org)
}
每次都会使用新的和干净的变量。你的问题将得到解决。
谢谢。希望对您有所帮助。
使用 gorm 和 postgres 在 Golang 中编写网络服务器时,我对以下代码中第二次循环迭代的确切情况产生了误解:
...
for _, t := range tasks {
newDbConn := db.SchoolServerDB.Debug().New()
err = newDbConn.Where("id = ?", t.DayID).First(&day).Error
if err != nil {
return errors.Wrapf(err, "Error query day with id='%v'", t.DayID)
}
...
}
...
第一次迭代调试:
SELECT * FROM "days" WHERE "days"."deleted_at" IS NULL AND ((id = '8')) ORDER BY "days"."id" ASC LIMIT 1
第二次迭代调试:
SELECT * FROM "days" WHERE "days"."deleted_at" IS NULL AND "days"."id" = '8' AND ((id = '38')) ORDER BY "days"."id" ASC LIMIT 1
关键问题是:尽管每次迭代都会创建一个新连接,但为什么会累积搜索条件?根据docs搜索条件每次都要清除。我想得到这样的第二个结果:
SELECT * FROM "days" WHERE "days"."deleted_at" IS NULL AND ((id = '38')) ORDER BY "days"."id" ASC LIMIT 1
感谢任何帮助!
UPD:
db.SchoolServerDb 只是 *gorm.DB 而 Debug() 是它的方法
Table 'days' 由结构日组成:
type Day struct {
gorm.Model
StudentID uint // parent id
Date string `sql:"size:255"`
Tasks []Task // has-many relation
Lessons []Lesson // has-many relation
}
您的搜索条件没有问题。您只需在第二次迭代的查询中提供多个 ID。一个在 Where
中,另一个在 Find
中。
让我写一个像你这样的例子
ids := []int{1, 2}
var org database.Organization
for _, i := range ids {
db, _ := connection.NewPGConnection(info)
db = db.Debug().New()
db.Where("id = ?", i).Find(&org)
}
这里,SQL第一次迭代查询如下:
SELECT * FROM "organizations" WHERE "organizations"."deleted_at" IS NULL AND ((id = '1'))
在第二次迭代中它将是:
SELECT * FROM "organizations" WHERE "organizations"."deleted_at" IS NULL AND "organizations"."id" = '1' AND "organizations"."code" = 'mir' AND ((id = '2'))
为什么?因为,您使用了相同的变量 day 来读取行结果。
第一次,还可以。但是第二次,您的 day 变量中已经有一个 ID。并且您在 Where
中提供了另一个。这就是为什么它的 运行 查询有两个 ID。
You are actually providing two
id
, one inwhere
clause and another inFind
.
更改代码以每次重新声明变量 day。像这样。
ids := []int{1, 2}
for _, i := range ids {
db, _ := connection.NewPGConnection(info)
db = db.Debug().New()
var org database.Organization // <----- move your variable day here
db.Where("id = ?", i).Find(&org)
}
每次都会使用新的和干净的变量。你的问题将得到解决。
谢谢。希望对您有所帮助。