房间 - 选择带有 IN 条件的查询?
Posted
技术标签:
【中文标题】房间 - 选择带有 IN 条件的查询?【英文标题】:Room - Select query with IN condition? 【发布时间】:2018-07-02 12:56:11 【问题描述】:是否可以在 Room 中使用 SQLite 的 IN
条件?
我正在尝试从我的数据库中选择一个项目列表,其中某个列的值(在本例中为 TEXT
列)与一组过滤器值中的任何一个匹配。据我所知,这在 SQL 和 SQLite 中很容易完成,只需在 SELECT
语句 (see here) 中添加 IN
条件即可。但是,我似乎无法让它与 Room 一起使用。
我不断收到此错误:
Error:(70, 25) error: no viable alternative at input 'SELECT * FROM Table WHERE column IN :filterValues'
(其中DAO @Query
-annotated 方法的输入称为filterValues
)
我现在尝试了三种不同的方法:
-
将参数作为
List<String>
传递
将参数作为String[]
传递
最后将参数传递为简单的String
,但格式为(value_1, value_2, ..., value_n)
最后一个应该很容易工作,因为它将(或至少应该)直接转换为SELECT * FROM Table WHERE column IN (value_1, value_2, ..., value_n)
,如果您只是访问直接数据库。
【问题讨论】:
***.com/a/48370198/115145 @CommonsWare 是的,这会立即解决我的问题。不幸的是,我在所有搜索中都没有遇到过这个问题,因为我专门寻找有关 Room 和SELECT
的信息,并带有 IN
条件(该问题中实际上没有提到)。
请注意,the question 中提到了所有这些内容。
【参考方案1】:
所以当我准备提交这个问题时,我仔细检查了一堆我之前查过的东西,发现我不知何故错过了一些东西,并且可以避免这个问题的必要性。
事实证明,这两个选项:
-
将参数作为
List<String>
传递
将参数作为String[]
传递
是可行的(并且您可以将String
替换为数据库可以表示的任何类型,例如char
或int
),您只需从以下位置更改@Query
注释中的语法:
@Query("SELECT * FROM Table WHERE column IN :filterValues")
到这里:
@Query("SELECT * FROM Table WHERE column IN (:filterValues)")
很容易,对吧?
请注意,Room 似乎不支持上面的第三种方法(将参数简单地传递为String
,但格式化为(value_1, value_2, ..., value_n)
),但这可能不是一件坏事,因为这是一种艰难的方式。
由于我已经输入了整个内容,我想我会留下这个问题,以防其他人像我一样难以找到这个解决方案并偶然发现这个问题。
【讨论】:
有什么方法可以让它与自定义类一起工作?例如。枚举。它似乎没有使用 TypeConverter 来转换自定义类的列表。 不确定我是否完全理解 - 您想搜索自定义对象的集合/列表吗?自定义对象/类可以在带有@TypeConverter
s 的 Room 中使用,但这用于将整个表格(或该表格列的子集)转换为一个类(反之亦然)。 SQL 查询搜索/索引各个列,这些列仍必须是 SQL 支持的数据类型(String、Int 等)。除了传递自定义对象列表之外,您可以做的是让多个参数对应于这些对象中的某些字段,每个参数映射到单个列。
例如@Query("SELECT * FROM agenda WHERE day IN (:days)") fun getAgenda(days: List<DayOfWeek>)
其中enum class DayOfWeek MON, TUES, ...
。 TypeConverter
可用于在所有其他上下文中查询/获取 DayOfWeek
,除了(似乎)IN
我猜问题是TypeConverter
不知道如何解析列表。尝试制作一个接受 List您好,您可以使用以下查询:
@Query("SELECT * FROM user WHERE uid IN(:userIds)")
public abstract List findByIds(int[] userIds);
或
@Query("SELECT * FROM user WHERE uid IN(:userIds)")
public abstract List findByIds(List<Integer> userIds);
【讨论】:
对我有用。非常感谢!【参考方案3】:与Kotlin
中的上述答案类似,您可以使用vararg
而不是array
或list
:
@Query("SELECT * FROM user WHERE uid IN (:userIds)")
fun getUsers(vararg userIds: Int): List<User>?
并像repository.getUsers(1, 2, 3)
一样使用它。
如果需要,将vararg
转换为list
请参阅https://proandroiddev.com/kotlins-vararg-and-spread-operator-4200c07d65e1(使用*
:format(output, *params)
)。
【讨论】:
以上是关于房间 - 选择带有 IN 条件的查询?的主要内容,如果未能解决你的问题,请参考以下文章
带有 where 条件的 PL/SQL 更新查询作为带有一些空值的选择查询