Java 合并多个LiveData源?
为了使我的问题更容易形象化,我画了如下图: 我使用的是RoomDatabase、存储库、Viewmodel和Livedata。区域与网关的关系为1:n,网关与项目的关系为1:n。 我创建了AreaWithGateways实体和GatewayWithItems实体 项目可以从一个网关移动到另一个网关,这就是为什么我使用Livedata观察它们,以跟踪它们所在的网关。我现在的问题是,我发现自己也需要跟踪哪些项目在哪些领域,我不知道如何做到这一点 我曾想过将每个网关的LiveData合并在一起,并观察到使用MediatorLiveData的情况,但我并不真正理解如何使用它。 或者可以使用GatewaySwithitems创建实体Area 如有任何见解,将不胜感激 编辑:我正在添加一些代码以使问题更清楚一些 这是区域实体Java 合并多个LiveData源?,java,android,repository,android-room,android-livedata,Java,Android,Repository,Android Room,Android Livedata,为了使我的问题更容易形象化,我画了如下图: 我使用的是RoomDatabase、存储库、Viewmodel和Livedata。区域与网关的关系为1:n,网关与项目的关系为1:n。 我创建了AreaWithGateways实体和GatewayWithItems实体 项目可以从一个网关移动到另一个网关,这就是为什么我使用Livedata观察它们,以跟踪它们所在的网关。我现在的问题是,我发现自己也需要跟踪哪些项目在哪些领域,我不知道如何做到这一点 我曾想过将每个网关的LiveData合并在一起,并观
@Entity(tableName = "area_table")
public class Area {
@PrimaryKey(autoGenerate = false)
private int areaId;
private String areaName;
private float wertX;
private float wertY;
private Boolean isDrawn;
public int getAreaId() {
return areaId;
}
public void setAreaId(int areaId) {
this.areaId = areaId;
}
public String getAreaName() {
return areaName;
}
public float getWertX() {
return wertX;
}
public float getWertY() {
return wertY;
}
public Boolean getDrawn() {
return isDrawn;
}
public Area(int areaId, String areaName, float wertX, float wertY, Boolean isDrawn) {
this.areaId = areaId;
this.areaName = areaName;
this.wertX = wertX;
this.wertY = wertY;
this.isDrawn = isDrawn;
}
}
网关实体:
@Entity(tableName = "gateway_table")
public class Gateway {
private float temp;
private String title;
private int areaId;
@PrimaryKey(autoGenerate = false)
private int gatewayId;
public int getGatewayId() {
return gatewayId;
}
public void setGatewayId(int gatewayId) {
this.gatewayId = gatewayId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public float getTemp() {
return temp;
}
public void setTemp(float temp) {
this.temp = temp;
}
public int getAreaId() {
return areaId;
}
public Gateway(int areaId, int gatewayId, String title) {
this.title = title;
this.areaId = areaId;
this.gatewayId = gatewayId;
}
}
以及项目实体:
@Entity(tableName = "cow_table")
public class Cow {
private int age;
private String sex;
private String name;
private boolean drawn;
private int gatewayId;
private String raceId;
@PrimaryKey(autoGenerate = false)
private int cowId;
public int getCowId() {
return cowId;
}
public void setCowId(int cowId) {
this.cowId = cowId;
}
public String getName() {
return name;
}
public boolean isDrawn() {
return drawn;
}
public int getAge() {
return age;
}
public String getSex() {
return sex;
}
public void setDrawn(boolean drawn) {
this.drawn = drawn;
}
public int getGatewayId() {
return gatewayId;
}
public String getRaceId() {
return raceId;
}
public Cow(int age, int cowId, int gatewayId,String name, String raceId, String sex, boolean drawn) {
this.age = age;
this.cowId = cowId;
this.sex= sex;
this.name = name;
this.drawn = drawn;
this.gatewayId = gatewayId;
this.raceId = raceId;
}
}
这是与网关的关系区域:
public class AreaWithGateways {
@Embedded
private Area area;
@Relation(parentColumn = "areaId",
entityColumn = "areaId")
private List<Gateway> gatewayList;
public Area getArea() {
return area;
}
public List<Gateway> getGatewayList() {
return gatewayList;
}
public AreaWithGateways(Area area, List<Gateway> gatewayList) {
this.area = area;
this.gatewayList = gatewayList;
}
}
以及网关,包括:
public class GatewayWithCows {
@Embedded
private Gateway gateway;
@Relation(parentColumn = "gatewayId",
entityColumn = "gatewayId")
private List<Cow> cowList;
public Gateway getGateway() {
return gateway;
}
public List<Cow> getCowList() {
return cowList;
}
public GatewayWithCows(Gateway gateway, List<Cow> cowList) {
this.gateway = gateway;
this.cowList = cowList;
}
}
我一直在试图找到一种方法,将某个区域中的所有项目作为Livedata获取,但仍然无法找到它。
我觉得我应该以某种方式使用AreaWithGateways将LiveData项添加到一起,但我无法通过网关访问这些项,只能通过另一种方式
或者可以使用GatewaySwithitems创建实体Area
不是用于定义表的实体,而是通过POJO使用@Embedded和@Relation注释(例如,您的GatewayWithCows是POJO)来定义表的实体
我觉得我应该以某种方式使用AreaWithGateways将LiveData项添加到一起,但我无法通过网关访问这些项,只能通过另一种方式
您基本上使用了分层方法,但POJO是这样的,因为您有GatewayWithCows,然后根据以下内容与该区域相关:-
class AreaWithGatewayWithCows {
@Embedded
Area area;
@Relation(entity = Gateway.class, parentColumn = "areaId",
entityColumn = "areaId")
List<GatewayWithCows> gatewayWithCowsList;
}
对LiveData进行了相应的修改。
请注意,如果在查询中使用联接,则诸如WHERE之类的任何子句只会影响区域的,而不会影响底层网关和Cows。也就是说,不管查询@Relation如何构建每个区域以及与该区域相关的所有网关;每个网关都会得到与该网关相关的所有奶牛。
为什么不使用N+1 LiveData作为最终目的地?模式中的所有LiveDatas都可以对新的N+1 LiveData执行LiveData.postValue,因此您只需观察他的最新版本。听起来这确实可以解决我的问题,但您将如何继续这样做?它应该在存储库中实现吗?这取决于如何将RoomDatabase与LiveData一起使用。您通常需要观察所有LiveData,然后在它们的每个onChangevalueee中执行finalLiveData.postValuevalueee。不幸的是,这种方法有一个中/大的缺点:太多的快速finalLiveData.postValue调用不会将它们的值都发布到finalLiveData,而是只将最新的值发布到finalLiveData。这取决于它是否适合您的需要。在我的情况下,更新每2到3秒进行一次。我用它们在地图上画出物品的位置,每当它们改变的时候。如果我要观察所有的livedata,然后使用postValue,那不是必须在一个活动/片段中吗?postValue可以从任何地方调用,并且它的消息在队列中。我使用引号,因为如果两个调用太快,最早的调用会被较新的调用覆盖,因此,主线程中没有真正的队列,然后使用较新的值引发FinalLiveData.onChange。谢谢!这真的很有帮助,我很难弄清楚如何在三个实体之间建立关系。虽然有没有一种方法可以将一个区域内每个网关的LiveData基本合并在一起?@HédiGuellouz那里可能我从来没有使用LiveData,我只是在房间的那一边涉猎过。然而,我的猜测是,你必须去从数据库中获取奶牛,这可能很复杂,因为它们必须是LiveData的。很确定使用LiveData是一条路。好吧!这样做的话,我应该观察LiveData,然后在每个List>中循环,然后在每个`List中再次循环。我要试试,希望这能解决我的问题problem@H是的,否则你就得观察所有的牛了
@Query("SELECT * FROM area_table")
List<AreaWithGatewayWithCows> getAreaWithGatewaysWithCows();