使用房间关系在房间数据库中三重加入

Posted

技术标签:

【中文标题】使用房间关系在房间数据库中三重加入【英文标题】:triple join in room database using room relation 【发布时间】:2021-10-16 16:12:00 【问题描述】:

我需要在房间中使用@relation anion 来三重连接我的实体,但我不知道如何。

这是我对实体的总结:

@Entity(tableName = "session_table")
data class Session(
    @PrimaryKey(autoGenerate = true)
    var sessionId: Long = 0L,

    @ColumnInfo(name = "lesson_id")
    var lessonId: Long
)

@Entity(tableName = "lessons_table")
data class Lesson(
    @PrimaryKey(autoGenerate = true)
    val lessonId: Long,

    @ColumnInfo(name = "teacher_id")
    var teacherId: Long = -1L
)

@Entity(tableName = "teacher_table")
data class Teacher(
    @PrimaryKey(autoGenerate = true)
    val teacherId: Long = 0L
) 

我认为答案是这样的:

data class SessionWithLessonWithTeacher(
    @Embedded
    val session: Session,

    @Relation(
        parentColumn = "lesson_id",
        entityColumn = "lessonId"
    )
    var lesson: Lesson,

    @Relation(
        parentColumn = "teacher_id", // this is the teacher id in lesson
        entityColumn = "teacherId",
    )
    var teacher: Teacher
)

【问题讨论】:

【参考方案1】:

您对SessionWithlessonWithTeacher 应该是什么的猜测是行不通的,因为它实际上是在说从Session 获取teacher_id。 Session 中没有teacher_id。

要使用@Relation,您需要遵循层次结构。一个会话有一个教训,一个教训有一个老师。因此,在 Session 中,您需要与老师一起上课。

因此(通过层次结构):-

data class LessonWithTeacher(
    @Embedded
    val lesson: Lesson,
    @Relation(
        entity = Teacher::class,
        parentColumn = "teacher_id",
        entityColumn = "teacherId")
    val teacher: Teacher
)

data class SessionWithLessonWithTeacher(
    @Embedded
    val session: Session,
    @Relation(
        entity = Lesson::class, /* NOTE Lesson  NOT LessonWithTeacher (not a table) */
        parentColumn = "lesson_id",
        entityColumn = "lessonId")
    val lessonWithTeacher: LessonWithTeacher
)

您可以使用@Dao,例如:-

@Query("SELECT * FROM session_table")
@Transaction
abstract fun getSessionWithLessonWithTeacher(): List<SessionWithLessonWithTeacher>

替代方法

Room 使用 @Relation 的方式是它最初只检索 Embedded 对象,然后通过后续查询检索所有 @Related 对象,因此它警告(期望)@Transaction。

对于您的场景,每节课有 1 节课,每节课有 1 位教师,您可以嵌入所有三个并有一个查询(尽管更复杂)JOIN 的三个表。

所以你可以有:-

data class SessionLessonTeacher(
    @Embedded
    val session: Session,
    @Embedded
    val lesson: Lesson,
    @Embedded
    val teacher: Teacher
)
注意,如果列名在嵌入对象之间不是唯一的,@Embedded 可能会很麻烦

等效的查询将/可能是:-

@Query("SELECT * FROM session_table " +
        "JOIN lessons_table ON lessons_table.lessonId = session_table.lesson_id " +
        "JOIN teacher_table ON teacher_table.teacherId = lessons_table.teacher_id")
abstract fun getSessionLessonTeacher(): List<SessionLessonTeacher>
请注意,在您的情况下,table.column 可能只是列,因为列名都是唯一的。

【讨论】:

以上是关于使用房间关系在房间数据库中三重加入的主要内容,如果未能解决你的问题,请参考以下文章

在 NestJs 中使用 Socket IO 加入和发射到房间

在房间数据库 Android 中返回带有嵌套关系的空数据

在 agsxmpp 中发现加入的房间

error96进入房间失败啥意思

房间数据库中具有一对多关系的 Where 子句

使用 Android 房间数据库在同一张表中的一对多关系