房间持久性库查询 COLLATE LOCALIZED 不起作用
Room Persistance Library Query COLLATE LOCALIZED not working
我使用的是今年 Google I/O 发布的新 Room Persistance Library ,到目前为止效果很好,但不知何故无法使用 [=19 对结果进行排序=]UNICODE 或 LOCALIZED。唯一有用的是 NOCASE,这对我来说没用。
有什么方法可以实现这个功能吗?
@Dao
public interface ContactDao {
@Query("SELECT * FROM contact ORDER BY lastName COLLATE LOCALIZED")
Flowable<List<Contact>> getAll();
}
如果我像上面那样构建查询,我会得到一个错误:
Error:(21, 29) error: There is a problem with the query: [SQLITE_ERROR]
SQL error or missing database (no such collation sequence: LOCALIZED)
在按以下方式定义列时使用 COLLATE
,
@ColumnInfo(collate = NOCASE) var name: String
它对我来说很好用。
无需在 Query
.
中指定 COLLATE
LOCALIZED
Room
中也没有整理
我不知道为什么 LOCALIZED 排序规则在文档中(https://developer.android.com/reference/android/arch/persistence/room/ColumnInfo.html#LOCALIZED). I found this issue report https://issuetracker.google.com/issues/68925249 已标记为已修复 - 但可能未发布。
所以有一个丑陋的解决方法,正如 CommonsWare 所评论的那样 - 在 CREATE 语句中定义它。这可以通过数据库构建器中的回调来实现。但是有问题——我们必须使用 create table 因为 sqlite 不支持 alter collate。而且因为 table 在回调中还存在,我们必须删除这个 table.
有我的实现(在 Kotlin 中)- 创建语句必须复制实体 class 定义也带有索引:
@Database(entities = [(LocalityItem::class)], version = AppDatabase.DB_VERSION, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun localityDao(): LocalityDao
companion object {
const val DB_NAME : String = "app_db"
const val DB_VERSION : Int = 1
private var INSTANCE: AppDatabase? = null
private val CALLBACK: Callback = object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
db.execSQL("DROP TABLE `locality` ")
db.execSQL("CREATE TABLE `locality` ("
+ " `id` INTEGER,"
+ " `type` INTEGER,"
+ " `name` TEXT COLLATE LOCALIZED, "
+ " `row_index` INTEGER,"
+ " `col_index` INTEGER,"
+ " PRIMARY KEY(`id`)"
+ ")")
db.execSQL("CREATE INDEX `index_locality_type` ON `locality` (`type`)")
db.execSQL("CREATE INDEX `index_locality_name` ON `locality` (`name`)")
}
}
fun getInstance(context : Context) : AppDatabase? {
if (INSTANCE == null) {
synchronized(AppDatabase::class) {
INSTANCE = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java, DB_NAME)
.addCallback(CALLBACK)
.build()
}
}
return INSTANCE
}
}
}
你必须使用这些版本的房间
compile "android.arch.persistence.room:runtime:1.1.1"
annotationProcessor "android.arch.persistence.room:compiler:1.1.1"
更新房间后 gradle 行
你可以使用这个功能
@ColumnInfo(整理=ColumnInfo.NOCASE)
我使用的是今年 Google I/O 发布的新 Room Persistance Library ,到目前为止效果很好,但不知何故无法使用 [=19 对结果进行排序=]UNICODE 或 LOCALIZED。唯一有用的是 NOCASE,这对我来说没用。
有什么方法可以实现这个功能吗?
@Dao
public interface ContactDao {
@Query("SELECT * FROM contact ORDER BY lastName COLLATE LOCALIZED")
Flowable<List<Contact>> getAll();
}
如果我像上面那样构建查询,我会得到一个错误:
Error:(21, 29) error: There is a problem with the query: [SQLITE_ERROR]
SQL error or missing database (no such collation sequence: LOCALIZED)
在按以下方式定义列时使用 COLLATE
,
@ColumnInfo(collate = NOCASE) var name: String
它对我来说很好用。
无需在 Query
.
COLLATE
LOCALIZED
Room
我不知道为什么 LOCALIZED 排序规则在文档中(https://developer.android.com/reference/android/arch/persistence/room/ColumnInfo.html#LOCALIZED). I found this issue report https://issuetracker.google.com/issues/68925249 已标记为已修复 - 但可能未发布。
所以有一个丑陋的解决方法,正如 CommonsWare 所评论的那样 - 在 CREATE 语句中定义它。这可以通过数据库构建器中的回调来实现。但是有问题——我们必须使用 create table 因为 sqlite 不支持 alter collate。而且因为 table 在回调中还存在,我们必须删除这个 table.
有我的实现(在 Kotlin 中)- 创建语句必须复制实体 class 定义也带有索引:
@Database(entities = [(LocalityItem::class)], version = AppDatabase.DB_VERSION, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun localityDao(): LocalityDao
companion object {
const val DB_NAME : String = "app_db"
const val DB_VERSION : Int = 1
private var INSTANCE: AppDatabase? = null
private val CALLBACK: Callback = object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
db.execSQL("DROP TABLE `locality` ")
db.execSQL("CREATE TABLE `locality` ("
+ " `id` INTEGER,"
+ " `type` INTEGER,"
+ " `name` TEXT COLLATE LOCALIZED, "
+ " `row_index` INTEGER,"
+ " `col_index` INTEGER,"
+ " PRIMARY KEY(`id`)"
+ ")")
db.execSQL("CREATE INDEX `index_locality_type` ON `locality` (`type`)")
db.execSQL("CREATE INDEX `index_locality_name` ON `locality` (`name`)")
}
}
fun getInstance(context : Context) : AppDatabase? {
if (INSTANCE == null) {
synchronized(AppDatabase::class) {
INSTANCE = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java, DB_NAME)
.addCallback(CALLBACK)
.build()
}
}
return INSTANCE
}
}
}
你必须使用这些版本的房间
compile "android.arch.persistence.room:runtime:1.1.1"
annotationProcessor "android.arch.persistence.room:compiler:1.1.1"
更新房间后 gradle 行
你可以使用这个功能
@ColumnInfo(整理=ColumnInfo.NOCASE)