【问题标题】:How to write a gorm function for where clause with dynamic variables如何为带有动态变量的where子句编写gorm函数
【发布时间】:2021-07-27 21:22:39
【问题描述】:

我需要创建一个 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 函数是否可行?

【问题讨论】:

    标签: go go-gorm


    【解决方案1】:

    您可以在.Where() 中使用map[string]interface{} 进行编码

    m := make(map[string]interface{})
    m["id"] = 10
    m["name"] = "chetan"
    db.Where(m).Find(&users)
    

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

    或者你可以在.Where() 中使用struct。创建一个struct变量,并在where中设置要查询和发送的字段

    db.Where(&User{Name: "chetan", Gender: "Male"}).First(&user)
    

    注意:使用struct查询时,GORM只会查询那些非零值的字段,也就是说如果你的字段的值为0、''、false或其他零值,它就赢了'不用于构建查询条件。

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

    【讨论】:

      【解决方案2】:

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

      在下面的例子中,我准备了field1field2,还有value1value2分别代表我要过滤的字段的名称和它们的值。

      值可以是任何类型,因为它是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

      如果我不确定我将传递多少个参数怎么办?在这种情况下,我们将硬编码为两个。如果该函数/方法通过 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

      【讨论】:

      • 这是有道理的。我应该更好地问我的问题。我已经编辑了我的问题。如果我不确定我将传递的参数数量是多少?在这种情况下,我们将硬编码为两个。如果该函数/方法通过 3 怎么办?
      • @Chetan 我的建议,阅读有关 gorm 的文档。 .Where() 方法的方案使我们非常容易应用动态 where 子句。第一个参数是一个字符串(易于构造查询),其余参数是切片(我们可以在那里传递任何参数)
      • 会的。谢谢。
      猜你喜欢
      • 2016-08-23
      • 1970-01-01
      • 2019-08-08
      • 1970-01-01
      • 1970-01-01
      • 2014-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多