Golang GORM实现不区分大小写查询的原理及实现问询
为什么这段代码能实现不区分大小写查询?
核心逻辑很简单:把数据库字段值和查询参数统一转成相同大小写(这里是大写)后再做匹配,彻底消除大小写差异带来的匹配问题。
咱们拆开来看看这段代码的逻辑:
UPPER(name):数据库执行查询时,会把name字段的每一条记录值都转换成大写形式UPPER(?):把你传入的查询参数(也就是拼接了通配符的%"+name+"%")也转换成大写LIKE:用来做模糊匹配,此时两边都是统一的大写——不管原数据是Apple、APPLE还是apple,转成大写后都是APPLE,只要查询参数转大写后包含在其中,就能匹配成功。
对应的SQL示例用的是=精确匹配,逻辑和上面一致:把字段值和查询值都转大写后再判断相等,自然就不区分大小写了。
实现不区分大小写查询的几种实用方式
除了你给出的写法,还有这些靠谱的实现方式:
1. 用LOWER替代UPPER(效果完全一致)
把两边都转成小写,逻辑和大写没区别,比如GORM代码:
DB.Select("name, vin_id").Where("LOWER(name) LIKE LOWER(?)", "%"+name+"%").Find(&vins)
对应的SQL:
select * from Table_Name where LOWER(Column_Name) = LOWER('mY Any Value')
2. GORM表达式写法(更贴合ORM风格)
用GORM的Expr方法,写法更清晰直观:
DB.Select("name, vin_id").Where(gorm.Expr("UPPER(name) LIKE UPPER(?)", "%"+name+"%")).Find(&vins)
3. 别忘优化索引(大数据量必看)
如果你的表数据量很大,直接用UPPER(name)会导致name字段的普通索引失效,查询速度变慢。可以给字段的大写形式建函数索引:
CREATE INDEX idx_name_upper ON Table_Name(UPPER(name));
这样数据库就能利用这个索引来加速不区分大小写的查询了。
4. 数据库全局配置(适合全表不需要区分大小写的场景)
比如MySQL可以把表或字段的字符集设置为utf8mb4_general_ci(_ci代表大小写不敏感),这样直接用普通的LIKE或=就能实现不区分大小写查询,不用手动转大小写:
// 直接写就能匹配,不需要UPPER/LOWER DB.Select("name, vin_id").Where("name LIKE ?", "%"+name+"%").Find(&vins)
不过这种方式是全局生效的,如果你的业务里有部分查询需要严格区分大小写,就不适合用这种方法。
内容的提问来源于stack exchange,提问作者Pavel
相关产品推荐
相关产品推荐

