热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何在Room中过滤嵌套关系?

如何解决《如何在Room中过滤嵌套关系?》经验,应该怎么办?

让我们举个例子:我有一个表单,其中有几个部分,每个部分都有问题.侧面,我有答案映射到问题,他们有另一列,我想在查询时过滤:

数据库架构

所以我有以下实体:

@Entity(tableName = "sections")
public class Section {
    @PrimaryKey
    public long id;
    public String title;
}
@Entity(tableName = "questions")
public class Question {
    @PrimaryKey
    public long id;
    public String title;
    public long sectionId;
}
@Entity(tableName = "answers")
public class Answer {
    @PrimaryKey
    public long id;
    public long questionId;
    public int otherColumn;
}

在DAO部分,我想要检索所有这些.

这是我想通过此查询填充的POJO:

class SectionWithQuestions {
    @Embedded
    public Section section;

    @Relation(parentColumn = "id", entityColumn = "sectionId", entity = Question.class)
    public List questions;

    public static class QuestionWithAnswer {
        @Embedded
        public Question question;

        @Relation(parentColumn = "id", entityColumn = "questionId", entity = Answer.class)
        List answers;
    }
}

在另一个应用程序中,查询将是:

SELECT s.*, q.*, a.*
FROM sections s
LEFT JOIN questions q ON q.sectiOnId= s.id
LEFT JOIN answers a ON a.questiOnId= q.id
WHERE s.id = :sectionId and a.otherColumn = :otherColumn

但是在Room中我发现如果你想要一个对象及其关系(如示例中的用户及其宠物),则只选择该对象,并在第二个查询中查询关系.那将是:

@Query("SELECT * FROM sections WHERE id = :sectionId")

然后在生成的代码中会有(伪代码):

sql = "SELECT * FROM sections WHERE id = :sectionId" // what's inside @Query
cursor = query(sql)
int indexColumn1 = cursor.getColumnIndex(col1)
int indexColumn2
... etc
while (cursor.moveToNext) {
    masterObject = new object()
    masterObject.property1 = cursor.get(indexColumn1)
    ... etc

    __fetchRelationshipXXXAsYYY(masterObject.relations) // fetch the child objects
}

这个__fetch XXX as YYY方法如下:

sql = "SELECT field1, field2, ... FROM a WHERE foreignId IN (...)"
similar algo as previously: fetch column indices, and loop through the cursor

所以基本上它创建了2个查询:一个用于主对象,一个用于关系.第二个查询是自动创建的,我们无法控制它.

为了回到我想要关系的问题,但也过滤了子列,我陷入困境:

在第一个查询中,我无法引用该otherColumn列,因为它不存在

@Relation我不能,因为这个注释的唯一属性是连接列和实体定义

这可能在房间里,还是我必须自己制作子查询?

奖金问题:为什么他们不在一个查询中连接表,而是创建2个查询?这是出于性能原因吗?


编辑以澄清我的期望:

这就是我期望写的:

@Query("SELECT s.*, q.*, a.* " +
       "FROM sections s " +
       "LEFT JOIN questions q ON q.sectiOnId= s.id " +
       "LEFT JOIN answers a ON a.questiOnId= q.id " +
       "WHERE s.id = :sectionId and a.otherColumn = :additionalIntegerFilter")
SectionWithQuestionsAndAnswers fetchFullSectionData(long sectionId);

static class SectionWithQuestionsAndAnswers {
    @Embedded Section section;
    @Relation(parentColumn = "id", entityColumn = "sectionId", entity = Question.class)
    List questions;
}
static class QuestionWithAnswers {
    @Embedded Question question;
    @Relation(parentColumn = "id", entityColumn = "questionId", entity = Answer.class)
    Answer answer; // I already know that @Relation expects List<> or Set<> which is
                   // not useful if I know I have zero or one relation (ensured
                   // through unique keys)
}

这是我想象由Room实现的伪代码作为生成的代码:

function fetchFullSectionData(long sectionId, long additionalIntegerFilter) {
    query = prepare(sql); // from @Query
    query.bindLong("sectionId", sectionId);
    query.bindLong("additionalIntegerFilter", additionalIntegerFilter);
    cursor = query.execute();
    Section section = null;
    long prevQuestiOnId= 0;
    Question question = null;
    while (cursor.hasNext()) {
        if (section == null) {
            section = new Section();
            section.questiOns= new ArrayList<>();
            section.field1 = cursor.get(col1); // etc for all fields
        }
        if (prevQuestionId != cursor.get(questionIdColId)) {
            if (question != null) {
                section.questions.add(question);
            }
            question = new Question();
            question.fiedl1 = cursor.get(col1); // etc for all fields
            prevQuestiOnId= question.id;
        }
        if (cursor.get(answerIdColId) != null) { // has answer
            Answer answer = new Answer();
            answer.field1 = cursor.get(col1); // etc for all fields
            question.answer = answer;
        }
    }
    if (section !=null && question != null) {
        section.questions.add(question);
    }
    return section;
}

这是一个查询,我的所有对象都被提取.


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
author-avatar
手机用户2502924641
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有