【问题标题】:Query 1:many relation in Android Room查询1:Android Room中的多关系
【发布时间】:2022-01-13 16:32:06
【问题描述】:

我在我的 Android 应用程序 (Java) 中使用 Room,我有两个具有 1:many 关系的实体。

镜头实体 一个镜片可以多次佩戴。

@Entity(tableName = "lens_table")
public class Lens {

    @PrimaryKey(autoGenerate = true)
    private int lensId;
    private String name;
}

穿戴实体 一次佩戴只能与一个镜头相关。

@Entity(tableName = "wear_table",
        foreignKeys = {@ForeignKey(
                entity = Lens.class,
                parentColumns = "lensId",
                childColumns = "fk_lensId",
                onDelete = ForeignKey.CASCADE)},
        indices = {@Index("fk_lensId")})
public class Wear {

    @PrimaryKey(autoGenerate = true)
    private int wearId;
    private String name;
    private int fk_lensId;
}

到目前为止一切顺利。到目前为止,我对“标准”查询(创建、获取所有、更新、删除......)很好,其中有很多文档。我还成功实施了查询,以根据以下关系获取所有镜片及其佩戴情况。

public class LensWithWears {

    @Embedded
    public Lens lens;

    @Relation(
            parentColumn = "lensId",
            entityColumn = "fk_lensId"
    )
    public List<Wear> wears;
}

但现在我需要查询以下信息:

通过查找wearId 获得带有关联镜片的单次佩戴

我目前使用的关系类如下所示:

public class WearWithLens {
    @Embedded
    public Wear wear;

    @Relation(
            parentColumn = "wearId",
            entityColumn = "lensId"
    )
    public Lens lens;
}

道查询看起来像这样:

@Query("SELECT * FROM wear_table WHERE wearId = :wearId LIMIT 1")
LiveData<WearWithLens> getWearWithLensByWearId(int wearId);

我的代码显然不起作用,否则我不会问... 问题是,返回了一个对象 WearWithLens,但其中的镜头对象始终为空。

换句话说,我想查询一个与镜头具有 1:1 关系的 Wear,并将两个对象放在 WearWithLens 类中。

有人可以告诉我查询应该是什么样子吗?

谢谢!

【问题讨论】:

    标签: java android sqlite foreign-keys android-room


    【解决方案1】:

    父列需要是形成两者关系的列。那应该是fk_lensId 列。

    所以:-

    public class WearWithLens {
        @Embedded
        public Wear wear;
    
        @Relation(
                parentColumn = "fk_lensId",
                entityColumn = "lensId"
        )
        public Lens lens;
    }
    

    举个例子

    • 为了方便和简洁,不使用LiveData&lt;WearWithLens&gt; getWearWithLensByWearId(int wearId);,而是使用WearWithLens getWearWithLensByWearId(int wearId);
    • 使用添加了 getter 和 setter 的类/实体以及额外的构造函数来减少编码
    • 显然是上述@Relationship。

    使用以下内容:-

        db = TheDatabase.getInstance(this);
        dao = db.getAllDao();
    
        int l1id = (int) dao.insert(new Lens("Lens1"));
        int l2id = (int) dao.insert(new Lens("Lens2"));
        int l3id = (int) dao.insert(new Lens("Lens3"));
    
        dao.insert(new Wear("Wear1 child of Lens1",l1id));
        dao.insert(new Wear("Wear2 child of Lens1",l1id));
        dao.insert(new Wear("Wear3 child of Lens1",l1id));
        dao.insert(new Wear("Wear4 child of Lens2",l2id));
        dao.insert(new Wear("Wear5 child of Lens2",l2id));
        dao.insert(new Wear("Wear6 child of Lens2",l2id));
        dao.insert(new Wear("Wear7 child of Lens3",l3id));
    
        for (Wear wear: dao.getAllWears()) {
            WearWithLens currentWearWithLens = dao.getWearWithLensByWearId(wear.getWearId());
            Log.d("DBINFO","Current Wear is " + currentWearWithLens.wear.getName() + " parent Lens is " + currentWearWithLens.lens.getName());
        }
    

    结果是:-

    2021-12-09 06:34:58.105 D/DBINFO: Current Wear is Wear1 child of Lens1 parent Lens is Lens1
    2021-12-09 06:34:58.110 D/DBINFO: Current Wear is Wear2 child of Lens1 parent Lens is Lens1
    2021-12-09 06:34:58.112 D/DBINFO: Current Wear is Wear3 child of Lens1 parent Lens is Lens1
    2021-12-09 06:34:58.114 D/DBINFO: Current Wear is Wear4 child of Lens2 parent Lens is Lens2
    2021-12-09 06:34:58.115 D/DBINFO: Current Wear is Wear5 child of Lens2 parent Lens is Lens2
    2021-12-09 06:34:58.116 D/DBINFO: Current Wear is Wear6 child of Lens2 parent Lens is Lens2
    2021-12-09 06:34:58.120 D/DBINFO: Current Wear is Wear7 child of Lens3 parent Lens is Lens3
    

    【讨论】:

    • 谢谢! !uite 愚蠢的我将wearId 放入父列....这显然行不通。关于您的其他输入 - 我已经删除了此处代码示例的构造函数、getter 和 setter,当然我已经实现了它们。我不确定的唯一一点是最后一点:在没有 LiveData 的情况下实现这一点会迫使我在主线程上执行请求,还是不执行?今天晚上我需要再试一次,但我尝试了类似的方法,但由于结果为空而导致异常。进一步 - db.getAllDao() 方法的背后是什么?能发一下代码吗?
    • @Zudy “我唯一不确定的一点是最后一点:在没有 LiveData 的情况下实现这一点会迫使我在主线程上执行请求,还是不执行?”如果处理/观察正确,LiveData 应该不会对结果产生影响。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 2022-08-18
    • 2021-02-23
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    相关资源
    最近更新 更多