روابط تودرتو را تعریف و پرس و جو کنید

گاهی اوقات، ممکن است نیاز داشته باشید مجموعه‌ای از سه یا چند جدول را که همگی به یکدیگر مرتبط هستند، جستجو کنید. در این صورت، باید روابط تو در تو بین جداول تعریف کنید.

فرض کنید در مثال برنامه پخش موسیقی، می‌خواهید از همه کاربران، همه لیست‌های پخش برای هر کاربر و همه آهنگ‌های موجود در هر لیست پخش برای هر کاربر، کوئری بگیرید. کاربران با لیست‌های پخش رابطه یک به چند دارند و لیست‌های پخش با آهنگ‌ها رابطه چند به چند دارند. مثال کد زیر کلاس‌هایی را که نمایانگر این موجودیت‌ها هستند و همچنین جدول ارجاع متقابل برای رابطه چند به چند بین لیست‌های پخش و آهنگ‌ها را نشان می‌دهد:

@Entity
data class User(
    @PrimaryKey val userId: Long,
    val name: String,
    val age: Int
)

@Entity
data class Playlist(
    @PrimaryKey val playlistId: Long,
    val userCreatorId: Long,
    val playlistName: String
)

@Entity
data class Song(
    @PrimaryKey val songId: Long,
    val songName: String,
    val artist: String
)

@Entity(primaryKeys = ["playlistId", "songId"], indices = [Index("playlistId", "songId")])
data class PlaylistSongCrossRef(
    val playlistId: Long,
    val songId: Long
)

First, model the relationship between two of the tables in your set as you normally do, using a data class and the @Relation annotation. The following example shows a PlaylistWithSongs class that models a many-to-many relationship between the Playlist entity class and the Song entity class:

data class PlaylistWithSongs(
    @Embedded val playlist: Playlist,
    @Relation(
        parentColumns = ["playlistId"],
        entityColumns = ["songId"],
        associateBy = Junction(PlaylistSongCrossRef::class)
    )
    val songs: List<Song>
)

پس از تعریف یک کلاس داده که این رابطه را نشان می‌دهد، یک کلاس داده دیگر ایجاد کنید که رابطه بین جدول دیگری از مجموعه شما و کلاس رابطه اول را مدل‌سازی کند و رابطه موجود را درون رابطه جدید "تو در تو" کند. مثال زیر یک کلاس UserWithPlaylistsAndSongs را نشان می‌دهد که یک رابطه یک به چند بین کلاس موجودیت User و کلاس رابطه PlaylistWithSongs مدل‌سازی می‌کند:

data class UserWithPlaylistsAndSongs(
    @Embedded val user: User,
    @Relation(
        entity = Playlist::class,
        parentColumns = ["userId"],
        entityColumns = ["userCreatorId"]
    )
    val playlists: List<PlaylistWithSongs>
)

کلاس UserWithPlaylistsAndSongs به طور غیرمستقیم روابط بین هر سه کلاس موجودیت: User ، Playlist و Song مدل‌سازی می‌کند. این موضوع در شکل 1 نشان داده شده است.

UserWithPlaylistsAndSongs رابطه بین User و PlaylistWithSongs را مدل‌سازی می‌کند، که به نوبه خود رابطه بین Playlist و Song را مدل‌سازی می‌کند.
شکل ۱. نمودار کلاس‌های رابطه در مثال برنامه پخش موسیقی.

If your set has more tables, create a class to model the relationship between each remaining table and the previous relationship class. This process creates a chain of nested relationships among all tables you want to query.

Finally, add a function to the data access object (DAO) class to expose the query function that your app needs. This function requires Room to run multiple queries, so add the @Transaction annotation so that the whole operation runs atomically:

@Transaction
@Query("SELECT * FROM User")
suspend fun getUsersWithPlaylistsAndSongs(): List<UserWithPlaylistsAndSongs>