android - 如何将条件应用于关系,或者如何正确处理 Room 中带有 WHERE 子句的 JOIN 查询?
问题描述
请耐心等待,我对架构组件和一般的 android 都是新手。我的问题与这个问题类似,但不幸的是,接受的答案似乎不起作用。我在 这个答案中有一个一对多关系的例子。我的示例数据库有两个表 USERS 和 PETS,如下图所示:
假设我想获取一个用户列表,其中包含按用户 ID 分组的宠物列表,只有小于 5 岁的宠物。结果应该如下所示(伪代码):
{uId:2,[Pet3,Pet4];uId:4,[宠物6,宠物7];}
另一个要求是 Dao 需要将列表作为 LiveData 对象返回,因为我使用的是 MVVM 架构并希望它能够感知生命周期和可观察。
有了这些要求,UserDao将如下所示:
@Dao
interface UserDao {
@Insert
void insert(User user);
@Transaction
@Query("SELECT USERS.uId, PETS.pId , PETS.userId, PETS.age " +
"FROM USERS INNER JOIN PETS ON PETS.userId = USERS.uId " +
"WHERE PETS.age < 5 " +
"GROUP BY USERS.uId")
LiveData<List<UserWithPets>> getUserPets();
}
用户实体:
@Entity
public class User {
@PrimaryKey
public int id; // User id
}
宠物实体:
@Entity
public class Pet {
@PrimaryKey
public int id; // Pet id
public int userId; // User id
public int age;
}
现在的问题是:我应该如何设计房间可以理解的 UserWithPets 并按照我想要的方式映射光标?这是我到目前为止所尝试的:
方法一:
在我看来,最方便的方法是使用关系,就像下面的 POJO 一样。
UserWithPets POJO:
public class UserWithPets {
@Embedded
public User user;
@Relation(parentColumn = "id", entityColumn = "userId", entity = Pet.class)
public List<Pet> pets;
}
不幸的是,谷歌尚未实现将条件分配给关系的功能。因此,对于拥有 5 岁以下宠物的每个用户,我们总是会获得完整的宠物列表。希望这将很快成为可能,因为功能请求已经分配在这里和这里。
谷歌在此功能请求中的声明:“我们计划实施一些查询重写逻辑来解决这些问题,不是针对 2.1,但希望在 2.2 中我们将更多地关注关系。”
方法二:
另一种选择是同时嵌入用户和宠物,例如:
public class UserWithPets {
@Embedded
public User user;
@Embedded
public Pet pet;
}
这也不起作用,因为现在我们每个用户只能得到 1 只宠物。
方法3:
这个答案建议只创建一个从用户扩展的合并类,例如:
public class UserWithPets extends User {
@Embedded(prefix = "PETS_")
List<Pet> pets = new ArrayList<>();
}
我尝试了很多方式,无论有没有构造器,但我无法让它工作。它总是给出错误,例如“实体和 Pojos 必须有一个可用的公共构造函数。你可以有一个空的构造函数或一个参数与字段匹配的构造函数(按名称和类型)。-java.util.List”或查询返回一些列... UserWithPets 不使用。所以这里欢迎任何建议。
方法4:
只需进行两个查询并将结果拼接在一起。我将如何使用 LiveData 做到这一点?加入操作应该在哪里进行?我不能在活动中做到这一点,这不是 MVVM 模式的重点。而且不在存储库或视图模型中,因为 LiveData 是不可变的。还是有其他方法?
获得上述要求的结果的可行解决方案是什么?
解决方案
推荐阅读
- java - 处理 onClick 和双击
- python - 如何在python中剪切一个熊猫列,并使另一列的长度相等?
- c - 将数组的指针传递给C中的函数
- ios - 自动布局和线性方程
- android - Android应用程序动态打开/关闭wifi热点
- python - 一段时间后,Selenium 中的 Chrome 驱动程序运行速度极慢
- javascript - 如何避免 JavaScript 中的“超出最大调用堆栈大小”错误?
- c++ - 分段错误(C++ 指针)
- java - SNIHostName 的 NoClassDefFoundError 异常
- django - 在 django 中为 geojson 数据创建 API