如何为带有动态变量的 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 ?
一种可能的解决方案是使用切片来保存条件。您将拥有动态调整 fields
和 values
.
的控件
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;
您可以在 .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 或其他零值,它不会用于构建查询条件。
我需要创建一个 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 ?
一种可能的解决方案是使用切片来保存条件。您将拥有动态调整 fields
和 values
.
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;
您可以在 .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 或其他零值,它不会用于构建查询条件。