You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Room持久化库中如何实现LIKE查询的大小写敏感?

在Android Room中实现大小写敏感的LIKE查询

我明白你遇到的问题了——设置PRAGMA case_sensitive_like = on后没生效,这其实是因为Room对数据库连接的管理方式导致的,单独执行这个PRAGMA语句可能无法覆盖所有Room使用的连接。下面给你几个可行的解决方案:

方案一:通过RoomDatabase Callback全局设置大小写敏感

Room允许我们在数据库打开时执行自定义SQL,我们可以利用这个特性,在每一个数据库连接打开时自动设置case_sensitive_like。这样所有的LIKE查询都会默认大小写敏感。

代码示例:

@Database(entities = [Category::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun categoryDao(): CategoryDao

    companion object {
        fun getInstance(context: Context): AppDatabase {
            return Room.databaseBuilder(context, AppDatabase::class.java, "your_db_name")
                .addCallback(object : RoomDatabase.Callback() {
                    override fun onOpen(db: SupportSQLiteDatabase) {
                        super.onOpen(db)
                        // 在数据库打开时执行PRAGMA设置
                        db.execSQL("PRAGMA case_sensitive_like = ON")
                    }
                })
                .build()
        }
    }
}

这个方法的好处是一次设置全局生效,不需要修改每个查询语句。

方案二:使用GLOB替代LIKE(原生大小写敏感)

SQLite的GLOB操作符默认就是大小写敏感的,它的匹配规则和LIKE类似,只是用*代替%,?代替_。你可以直接修改查询语句:

@Query("SELECT * FROM category WHERE category_name GLOB '*' || :categoryName || '*'")
List<Category> getAllCategory(@Nullable String categoryName);

这个方法适合只需要单个查询大小写敏感的场景,不需要全局修改。

方案三:在查询中使用COLLATE BINARY

你可以在LIKE查询后加上COLLATE BINARY,强制使用大小写敏感的排序规则,这样也能实现需求:

@Query("SELECT * FROM category WHERE category_name LIKE '%' || :categoryName || '%' COLLATE BINARY")
List<Category> getAllCategory(@Nullable String categoryName);

这个方法同样是针对单个查询,语法和原来的LIKE更贴近,学习成本更低。

为什么原来的PRAGMA设置没生效?

Room会维护自己的数据库连接池,如果你只是在某个单独的连接中执行PRAGMA case_sensitive_like = on,其他连接并不会继承这个设置。而通过RoomDatabase Callback的onOpen方法,Room会在每一个新打开的连接上执行这个SQL,确保所有连接都生效。

内容的提问来源于stack exchange,提问作者Lokesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:35:04