【问题标题】:Hardcode Boolean Query In Room Database房间数据库中的硬编码布尔查询
【发布时间】:2018-05-23 16:06:30
【问题描述】:

我正在构建一个 Android 应用程序,它会为用户显示潜在匹配项列表。用户可以点击一个点赞用户,我把所有点赞保存在本地。

我可以编写一个查询来获取匹配列表,如下所示:

@Query("SELECT * FROM match WHERE liked = :liked ORDER BY match DESC LIMIT :limit")
fun getMatches(limit: Int = 6, liked: Boolean = true): Flowable<List<Match>>

我了解到这很好用。但是,我没有预见到我会将liked 设置为false 的任何情况,所以我很好奇是否有办法对我的布尔条件进行硬编码?如果我尝试:

@Query("SELECT * FROM match WHERE liked = true ORDER BY match DESC LIMIT :limit")

我在编译时收到以下错误:

Error:(8, 0) Gradle: error: There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such column: true)

如何在我的查询字符串中硬编码这个布尔值?

我也试过了:

  • 将条件用单引号括起来
    • @Query("SELECT * FROM match WHERE liked = 'true' ORDER BY match DESC LIMIT :limit")

【问题讨论】:

    标签: android android-room


    【解决方案1】:

    SQLite 没有布尔数据类型。 Room 将其映射到 INTEGER 列,将 true 映射到 1false0

    所以,我希望这会起作用:

    @Query("SELECT * FROM match WHERE liked = 1 ORDER BY match DESC LIMIT :limit")
    

    请记住,此行为未记录在案。然而,它不应该改变——至少在没有警报响起的情况下不会改变——因为我们需要使用迁移来处理任何变化。

    【讨论】:

    • 成功了,谢谢!我绝对认为 Room 文档中遗漏了这一点。
    • @AdamMc331:特别是在他们最近一轮的更改之后,我认为 Room 文档中遗漏了 Room 文档。 :-( 但是,我很高兴它对你有用!
    • 好吧,我已经做到了! :P
    • 哦,是的,Room 文档非常少……谢谢!
    • Room 数据库显然为 True 生成 1,为 False 生成 1 购买我的查询返回 null 或空列表。可能是什么问题?
    【解决方案2】:

    CommonWare 的方法确实有效,而且还直接回答了 OP 的问题;但是,我不喜欢对数据库做出这样的假设。这个假设应该是安全的,但如果 R​​oom 决定改变它的布尔实现,它可能会在未来产生意想不到的工作。

    我建议更好的方法是不要将布尔值 1 或 0 硬编码到查询中。如果数据库位于存储库之后,存储库仍然可以公开优雅的 API。就个人而言,我认为从数据库实现中屏蔽更大的代码库是一件好事。

    道法(抄自OP的问题)

    @Query("SELECT * FROM match WHERE liked = :liked ORDER BY match DESC LIMIT :limit")
    fun getMatches(limit: Int = 6, liked: Boolean = true): Flowable<List<Match>>
    

    存储库

    class Repository {
        public Flowable<List<Match>> getLikedMatches() {
            return dao.getMatches(6, true);
        }
    }
    

    当然,这是一个固执己见的选择,因为它采用了某种架构风格。但是,它不对内部数据库做出假设。即使没有存储库屏蔽数据库,也可以通过在任何地方传递 true 来调用数据库 - 也无需对基础数据进行假设。

    【讨论】:

    • 如果你使用不同的建筑风格。可以直接在DAO定义中屏蔽默认值。但是您需要将 DAO 定义为抽象类,而不是接口。定义同上:@Query("SELECT * FROM match WHERE liked = :liked ORDER BY match DESC LIMIT :limit") protected abstract fun getMatches(limit: Int, liked: Boolean): Flowable&lt;List&lt;Match&gt;&gt;和公开版fun getLikedMatches(limit: Int = 6) = getMatches(limit, true)
    • “如果 Room 决定改变它的布尔实现” - 他们不能这样做,因为每个人在升级 Room 时都会“损坏”现有的布尔数据。我从未见过 Room 库更改的数据迁移逻辑。
    • “他们不能这样做”——他们可以。他们可能会做的很慢,但他们绝对可以。依赖 Room 的底层实现可能很危险。因为某些东西被暴露并不足以成为使用它的理由——尤其是当可以通过记录的行为获得相同的目的时。
    • “他们可以”,但这将是一个错误。我也可以编写错误代码,但令人惊讶的是,没有人喜欢这样。
    • 存储库更改其内部实现不是错误。我也可以简洁,但令人惊讶的是,没有人喜欢这样。
    【解决方案3】:

    您不必将布尔列与值进行比较。只需将列值本身用作布尔表达式。您可以轻松地将查询更改为SELECT * FROM match WHERE liked ORDER BY match DESC LIMIT :limit。 如果要与false 值进行比较,可以使用以下表达式:where not liked

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2022-09-27
      • 2018-06-18
      • 1970-01-01
      • 2020-02-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多