8

我正在使用今年 Google I/O 发布的新房间持久性库,到目前为止它运行良好,但不知何故,无法使用UNICODELOCALIZED对结果进行排序。唯一有效的是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)
4

3 回答 3

7

你必须使用这些版本的房间

compile "android.arch.persistence.room:runtime:1.1.1"
annotationProcessor "android.arch.persistence.room:compiler:1.1.1"

更新您的房间等级线后

你可以使用这个功能

@ColumnInfo(collat​​e = ColumnInfo.NOCASE)

于 2018-10-04T07:50:41.477 回答
1

我不知道为什么在文档中(https://developer.android.com/reference/android/arch/persistence/room/ColumnInfo.html#LOCALIZED )没有实现 LOCALIZED 排序规则(在 Room 版本 1.0.0 中) )。我发现这个问题报告https://issuetracker.google.com/issues/68925249被标记为已修复 - 但它可能没有发布。

因此,正如 CommonsWare 所评论的那样,有一个丑陋的解决方法 - 在 CREATE 语句中定义它。这可以通过数据库构建器中的回调来实现。但是有一个问题 - 我们必须使用 create table 因为 sqlite 不支持 alter collat​​e。由于回调中表还存在,我们必须删除该表。

有我的实现(在 Kotlin 中) - create 语句必须复制实体类定义也带有索引:

@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
        }
    }
}
于 2018-02-23T09:12:15.930 回答
-1

COLLATE在列定义时使用以下方式,

@ColumnInfo(collate = NOCASE) var name: String

它对我来说很好。无需COLLATEQuery.

也没有LOCALIZED校对Room

于 2018-02-23T06:47:21.723 回答