房间数据库中的硬编码布尔查询
Hardcode Boolean Query In Room Database
我正在构建一个 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")
SQLite 没有布尔数据类型。 Room 将其映射到 INTEGER
列,将 true
映射到 1
,将 false
映射到 0
。
所以,我希望它能起作用:
@Query("SELECT * FROM match WHERE liked = 1 ORDER BY match DESC LIMIT :limit")
请记住,此行为未记录在案。然而,它不应该改变——至少在没有警报响起的情况下——因为我们需要使用迁移来处理任何变化。
CommonWare 的方法确实有效,也直接回答了 OP 问题;但是,我不喜欢对数据库做出这样的假设。这个假设应该是安全的,但如果 Room 决定改变它的布尔实现,它可能会在未来产生意想不到的工作。
我建议更好的方法是不要将布尔值 1 或 0 硬编码到查询中。如果数据库在存储库后面,存储库仍然可以公开一个优雅的API。就个人而言,我认为从数据库实现中屏蔽更大的代码库无论如何都是一件好事。
Dao 方法(从 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 来对数据库进行调用 - 也无需对基础数据进行假设。
您不必将布尔列与值进行比较。只需将列值本身用作布尔表达式即可。您可以轻松地将查询更改为 SELECT * FROM match WHERE liked ORDER BY match DESC LIMIT :limit
。
如果要与 false
值进行比较,可以使用以下表达式:where not liked
.
我正在构建一个 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")
SQLite 没有布尔数据类型。 Room 将其映射到 INTEGER
列,将 true
映射到 1
,将 false
映射到 0
。
所以,我希望它能起作用:
@Query("SELECT * FROM match WHERE liked = 1 ORDER BY match DESC LIMIT :limit")
请记住,此行为未记录在案。然而,它不应该改变——至少在没有警报响起的情况下——因为我们需要使用迁移来处理任何变化。
CommonWare 的方法确实有效,也直接回答了 OP 问题;但是,我不喜欢对数据库做出这样的假设。这个假设应该是安全的,但如果 Room 决定改变它的布尔实现,它可能会在未来产生意想不到的工作。
我建议更好的方法是不要将布尔值 1 或 0 硬编码到查询中。如果数据库在存储库后面,存储库仍然可以公开一个优雅的API。就个人而言,我认为从数据库实现中屏蔽更大的代码库无论如何都是一件好事。
Dao 方法(从 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 来对数据库进行调用 - 也无需对基础数据进行假设。
您不必将布尔列与值进行比较。只需将列值本身用作布尔表达式即可。您可以轻松地将查询更改为 SELECT * FROM match WHERE liked ORDER BY match DESC LIMIT :limit
。
如果要与 false
值进行比较,可以使用以下表达式:where not liked
.