Java 合并多个LiveData源?

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合并在一起,并观

为了使我的问题更容易形象化,我画了如下图:

我使用的是RoomDatabase、存储库、Viewmodel和Livedata。区域与网关的关系为1:n,网关与项目的关系为1:n。 我创建了AreaWithGateways实体和GatewayWithItems实体

项目可以从一个网关移动到另一个网关,这就是为什么我使用Livedata观察它们,以跟踪它们所在的网关。我现在的问题是,我发现自己也需要跟踪哪些项目在哪些领域,我不知道如何做到这一点

我曾想过将每个网关的LiveData合并在一起,并观察到使用MediatorLiveData的情况,但我并不真正理解如何使用它。 或者可以使用GatewaySwithitems创建实体Area

如有任何见解,将不胜感激

编辑:我正在添加一些代码以使问题更清楚一些

这是区域实体

@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();