【问题标题】:Room Query: find within list is always returning null房间查询:在列表中查找总是返回 null
【发布时间】:2019-06-26 12:51:29
【问题描述】:

我有一个实体,其中一个字段是 MutableList。我想返回该列表中包含给定 ID 的所有用户 ID。查询总是返回一个空列表。如果我打开数据库,虽然我可以看到这些字段已正确存储并且有要返回的用户 ID。我究竟做错了什么?

数据类:

@Entity
data class User(
  @PrimaryKey
  @SerializedName("id")
  @ColumnInfo(name = "userId")
  var userId: String,
  @SerializedName("username")
  var userName: String = "",
  var city: String = "",
  var postsIds: MutableList<String>
)

道:

@Dao
interface UserDao {
   @Query("SELECT * FROM user WHERE postsIds LIKE :id")
   fun getForPost(id: String): List<User>

// some other queries
}

存储库:

fun getUsersForPost(id: String): LiveData<List<User>> {
        val data = MutableLiveData<List<User>>()
        GlobalScope.launch {
            val query = async(Dispatchers.IO) { userDao.getForPost(id) }
            val result = query.await()
            if (result.isNullOrEmpty()) {
                // todo fetch from the API
            } else {
                data.postValue(result)
            }
        }
        return data
    }

用法:

ViewModel: 

fun getPost(id: String): Post {
  val post = repository.getPost(id)
  _postEditors.value = repository.getUsersForPost(id).value
  return post
}

Fragment: 

viewModel.postEditors.observe(this, Observer { 
  Log.d(TAG, $it)
})

【问题讨论】:

    标签: android kotlin android-room android-architecture-components


    【解决方案1】:

    据我所知,您似乎使用的是 LIKE(通配符搜索) 而不是 = (完全匹配) 运算符:

        @Dao
        interface UserDao {
    
            @Query("SELECT * FROM user WHERE postsIds = :id")
            fun getForPost(id: String): List<User>
    
            // some other queries
        }
    

    现在我确定您有自己的用例来执行此操作。使用 Room 1.1.1+ 时,您需要向 LIKE 运算符添加通配符 %,如下所示,否则可能无法正常工作:

        @Dao
        interface UserDao {
    
            @Query("SELECT * FROM user WHERE postsIds LIKE `%` || :id || `%`")
            fun getForPost(id: String): List<User>
    
            // some other queries
        }
    

    注意: || is concatenation operator% wildcard 继续阅读 SQLite wildcards

    这将导致搜索与提供的id 匹配的任何内容 a.k.aFull Text Search,如果您只想匹配以 id 开头的任何内容,那么您可以执行以下操作:

       @Dao
       interface UserDao {
    
           @Query("SELECT * FROM user WHERE postsIds LIKE :id || `%`")
           fun getForPost(id: String): List<User>
    
           // some other queries
    }
    

    另一个提示,如果您真的想将 全文搜索 与 Room 一起使用,那么我建议您更新到添加了 FTS4 支持的 v2.1,这是关于Medium的详细阅读

    【讨论】:

      【解决方案2】:

      仅通过查看您的代码,我认为您正在执行userDao.getForPost(id),但您可能应该执行userDao.getForPost("%"+id+"%")

      【讨论】:

        猜你喜欢
        • 2021-09-01
        • 1970-01-01
        • 2022-06-16
        • 2022-12-18
        • 1970-01-01
        • 2021-01-15
        • 2018-09-18
        • 2019-11-26
        • 1970-01-01
        相关资源
        最近更新 更多