【问题标题】:Room Persistance Library Query COLLATE LOCALIZED not working房间持久性库查询 COLLATE LOCALIZED 不起作用
【发布时间】:2017-10-23 10:44:03
【问题描述】:

我正在使用今年 Google I/O 上发布的新 Room Persistance Library,到目前为止它运行良好,但不知何故,无法使用 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)

【问题讨论】:

  • 如果我理解正确,要使用COLLATE LOCALIZED,您需要在CREATE TABLE 语句中将其声明为列约束的一部分。看来您可以使用Migration 来编写自己的CREATE TABLE 语句,但我不清楚如何为初始表创建创建Migration(与升级相比)。我不知道您是否是提交this issue 的人,但我会留意它。
  • 嗨,你修好了吗?
  • 不是真的......目前我只是在使用之前对列表进行排序。 Collections.sort(nameOfYourList) { o1, o2 -&gt; Collator.getInstance(Locale.GERMAN).compare(o1.lastName, o2.lastName) }

标签: android database sqlite orm android-room


【解决方案1】:

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

@ColumnInfo(collate = NOCASE) var name: String

它对我来说很好用。 无需在Query 中指定COLLATE

Room 中也没有LOCALIZED 整理

【讨论】:

    【解决方案2】:

    我不知道为什么在文档 (https://developer.android.com/reference/android/arch/persistence/room/ColumnInfo.html#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
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

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

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

      更新房间等级线后

      你可以使用这个功能

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

      【讨论】:

      • 是的!这个问题很老了,但在较新的版本中,这个功能终于实现了。
      • @ColumnInfo(collat​​e = ColumnInfo.NOCASE)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-27
      • 2018-01-22
      • 1970-01-01
      • 2016-04-23
      • 1970-01-01
      • 2017-11-08
      • 2020-03-19
      相关资源
      最近更新 更多