Android Room @Relation 多对多?

MrV*_*lev 4 android many-to-many android-room android-livedata

我正在开发一个 android 应用程序,并在 Android 操作系统中使用新的架构组件:LiveData、ViewModel 和 Room。我对 Room 实现有一个关于创建 @Relation 的小问题,它返回 JOIN 查询(​​多对多关系)的结果。

我的数据库结构如下所示:

@Entity
public class Student{
  @PrimaryKey
  private int id;
  private String name;
  private String email;
} 

@Entity
public class Group{
  @PrimaryKey
  private int id;
  private String name;
}

@Entity(foreignKeys = {
            @ForeignKey(entity = Student.class,
                    parentColumns = "id",
                    childColumns = "student_id"),
            @ForeignKey(entity = Group.class,
                    parentColumns = "id",
                    childColumns = "group_id")
    })
public class StudentGroup{

  private int studentId;
  private int groupId;
}
Run Code Online (Sandbox Code Playgroud)

我如何才能为特定学生获取所有组,像这样?

public class StudentWithGroups{
  @Relation(parentColumn = "id", entityColumn = "rule_id", entity = 
StudentGroup.class)
  private List<Group> groups;
}
Run Code Online (Sandbox Code Playgroud)

我已经检查过诸如如何用 Android Room 表示多对多关系之类的问题?Android 持久化室:“无法弄清楚如何从光标读取此字段”

Nis*_*hal 5

通过介绍Junction in room,您可以轻松处理多对多关系。

修改学生表和组表的主键为:

@Entity
public class Student{
  @PrimaryKey
  private int sId;
  private String name;
  private String email;
} 

@Entity
public class Group{
  @PrimaryKey
  private int gId;
  private String name;
}

@Entity(foreignKeys = {
        @ForeignKey(entity = Student.class,
                parentColumns = "sId",
                childColumns = "studentId"),
        @ForeignKey(entity = Group.class,
                parentColumns = "gId",
                childColumns = "groupId")
})
public class StudentGroup{
  private int studentId;
  private int groupId;
}
Run Code Online (Sandbox Code Playgroud)

您可以将特定学生的所有组设为:

 public class StudentWithGroups{
   @Embedded
   Student student;
   @Relation(
         parentColumn = "sId",
         entity = Group.class,
         entityColumn = "gId",
         associateBy = @Junction(
                 value = StudentGroup.class,
                 parentColumn = "studentId",
                 entityColumn = "groupId)
   )
   List<Group> groups;
 }
Run Code Online (Sandbox Code Playgroud)

现在您可以查询数据库的结果为:

 @Dao
 public interface StudentDao {
   @Query("SELECT * FROM Student")
   List<StudentWithGroups> getGroupsOfStudent();
}
Run Code Online (Sandbox Code Playgroud)


Com*_*are 2

我如何才能获得仅针对特定学生的所有小组,类似的事情?

此示例代码中,我有:

  @Query("SELECT categories.* FROM categories\n"+
    "INNER JOIN customer_category_join ON categories.id=customer_category_join.categoryId\n"+
    "WHERE customer_category_join.customerId=:customerId")
List<Category> categoriesForCustomer(String customerId);
Run Code Online (Sandbox Code Playgroud)

将其转换为您的实体会产生如下结果:

  @Query("SELECT Group.* FROM Group\n"+
    "INNER JOIN StudentGroup ON Group.id=StudentGroup.groupId\n"+
    "WHERE StudentGroup.studentId=:studentId")
List<Group> groupsForStudent(String studentId);
Run Code Online (Sandbox Code Playgroud)

一般来说,使用 Room 计算出忽略 Room 的 SQL,然后在 DAO 中使用该 SQL。