如何为带有动态变量的 where 子句编写 gorm 函数

How to write a gorm function for where clause with dynamic variables

我需要创建一个 sql 查询:

SELECT * FROM users WHERE id = 10 AND name = "Chetan"

现在,gorm 的 where 函数如下所示,

// Where return a new relation, filter records with given conditions, accepts `map`, `struct` or `string` as conditions, refer http://jinzhu.github.io/gorm/crud.html#query
func (s *DB) Where(query interface{}, args ...interface{}) *DB {
    return s.clone().search.Where(query, args...).db
}

这意味着它接受查询和参数。示例:

dbDriver.Where("id = ?", id).First(t)

如何动态传递多个变量。示例:

SELECT * FROM users WHERE id = 10 AND name = "Chetan"
SELECT * FROM users WHERE id = 10
SELECT * FROM users WHERE gender = "male" AND name = "Chetan" AND age = "30"

是否可以为这样的动态 SQL 语句编写单个 gorm 函数?

.Where() 的第一个参数接受 string,其余参数是可变的,这意味着您可以修改查询和值。

在下面的示例中,我准备了 field1 & field2,还有 value1 & value2 来表示我要过滤的字段的名称以及它们的值。

The values can be in any type since it's interface{}.

var field1 string = "id"
var value1 interface{} = 10

var field2 string = "age"
var value2 interface{} = "30"

dbDriver.Where(field1 " = ? AND " + field2 + " = ?", value1, value2).First(t)

更新 1

What if i am not sure what are number of parameter i will be passing? In this case we are hardcoding to two. What if that function/method passes 3 ?

一种可能的解决方案是使用切片来保存条件。您将拥有动态调整 fieldsvalues.

的控件
fields := []string{"id = ?", "age = ?"}
values := []interface{}{10, "30"}

dbDriver.Where(strings.Join(fields, " AND "), values...).First(t)

更新 2

根据@Eklavya 的评论,也可以在 where 子句上使用预定义的结构对象或 map 而不是 string

db.Where(&User{Name: "jinzhu", Age: 20}).First(&user)
// SELECT * FROM users WHERE name = "jinzhu" AND age = 20 ORDER BY id LIMIT 1;

db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users)
// SELECT * FROM users WHERE name = "jinzhu" AND age = 20;

参考:GORM query reference

您可以在 .Where()

中使用 map[string]interface{} 进行编码
m := make(map[string]interface{})
m["id"] = 10
m["name"] = "chetan"
db.Where(m).Find(&users)

只需在地图中添加您的条件,然后在 where 内发送。

或者你可以在.Where()中使用struct。创建一个结构变量,并在 where

中设置要查询和发送的字段
db.Where(&User{Name: "chetan", Gender: "Male"}).First(&user)

注意:当使用结构查询时,GORM 只会查询那些具有非零值的字段,这意味着如果您的字段值为 0、''、false 或其他零值,它不会用于构建查询条件。

参考:https://gorm.io/docs/query.html#Struct-amp-Map