type notString string
const (
col1 notString = "col1"
)
func Test_not_a_string_type(t *testing.T) {
db := gorm_learn.SQLiteInMemoryDB(context.Background()).
Session(&gorm.Session{DryRun: true})
var val map[string]any
notStrCond := col1 + " IS NOT NULL"
err := db.Table("some_table").
Where(notStrCond).
Find(&val).
Error
if err != nil {
t.Error(err)
}
// [0.030ms] [rows:0] SELECT * FROM `some_table` WHERE `some_table`. = "col1 IS NOT NULL"
// not_a_string_type_test.go:35: model value required
fmt.Println()
// "col1 IS NOT NULL": col1 IS NOT NULL: not_a_string_type_test.notString
fmt.Printf("%q: %v: %T\n", notStrCond, notStrCond, notStrCond)
fmt.Println()
var a any = notStrCond
_, ok := a.(string)
fmt.Printf("notString is string?: %v\n", ok) // notString is string?: false
}
背景
在 gorm 中,可以使用
Where()
方法来添加条件:Where()
方法的第一个参数是any
类型,Where()
方法根据第一个参数的动态类型-也就是我们传递的实参的类型,来决定如何构建 SQL 语句。问题
下面的代码可以说明我碰到的问题,完整代码在这里。
在上面的代码中,虽然
notString
类型的 underlying type 是string
,但是它是和string
完全不同的新类型。常量col1
是notString
类型,变量notStrCond
也是notString
类型。变量notStrCond
被传递给Where()
方法作为第一个参数。我潜意识里认为自己传递的是
string
类型的参数,但是 gorm 并不认识这个自定义类型notString
,导致最后生成的 SQL 语句错误。解决方法
在将
notStrCond
传递给Where()
时,将其转换为string
类型:Where(string(notStrCond))
。