gorm 是否使用逻辑或来解释结构的内容?

Does gorm interpret the content of a struct with a logical OR?

SQL 的新手,我正在编写一个 API 中间件作为练习,它检查某些 header 中包含的信息是否与数据库条目匹配(“token-based 验证”)。数据库访问基于 GORM.

为此,我定义了我的 ORM 如下:

type User struct {
    ID       uint
    UserName string
    Token string
}

在我的中间件中,我检索了相关 header 的内容并以变量 userHeadertokenHeader 结尾。它们应该与数据库匹配才能进行身份验证。

user table 有一个条目:

select * from users 
// 1,admin,admintoken

验证码是

    var auth User
    res := db.Where(&User{UserName: userHeader, Token: tokenHeader}).Find(&auth)
    if res.RowsAffected == 1 {
        // authentication succeeded
    }

测试时,我得到以下两个 不正确的 结果(其他组合正确):

我希望我的查询是指(在上述错误结果的上下文中)

 select * from users where users.user_name = 'admin' and users.token = ''
 select * from users where users.user_name = '' and users.token = ''

并且此查询在控制台上是正确的,即产生零结果(运行 对数据库)。

然而,ORM 似乎丢弃了 non-existing headers 并假设它们没问题(至少这是我的理解)

我还尝试通过

链接Where子句
db.Where(&User{UserName: userHeader}).Where(&User{Token: tokenHeader}).Find(&auth) 

但结果是一样的

正确的查询应该是什么?

gorm.io 文档说明了在 Where 条件中使用结构的以下内容:

When querying with struct, GORM will only query with non-zero fields, that means if your field’s value is 0, '', false or other zero values, it won’t be used to build query conditions ...

建议的解决方案是:

To include zero values in the query conditions, you can use a map, which will include all key-values as query conditions ...


因此,当令牌头或两个头都为空时,但您仍想将它们包含在生成的查询的 WHERE 子句中,您需要使用 map 而不是结构作为 Where 方法的参数。

db.Where(map[string]interface{}{"user_name": userHeader, "token": tokenHeader}).Find(&auth)

您可以使用 Debug() 检查生成的 SQL (它被打印到 stderr 中);如果您不确定 SQL 您的代码生成什么

,请使用它