有時候,您可能需要查詢三組以上彼此相關的資料表。如果是這種情況,您可以定義資料表之間的「巢狀結構關係」。
在音樂串流應用程式範例中,假設您想查詢所有使用者、每位使用者的所有播放清單,以及每位使用者的每個播放清單中的所有歌曲。使用者與播放清單之間具有一對多關係,而播放清單與歌曲之間則有多對多關係。以下程式碼範例顯示代表這些實體的類別,以及播放清單與歌曲之間多對多關係的交叉參照資料表:
Kotlin
@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"])
data class PlaylistSongCrossRef(
val playlistId: Long,
val songId: Long
)
Java
@Entity
public class User {
@PrimaryKey public long userId;
public String name;
public int age;
}
@Entity
public class Playlist {
@PrimaryKey public long playlistId;
public long userCreatorId;
public String playlistName;
}
@Entity
public class Song {
@PrimaryKey public long songId;
public String songName;
public String artist;
}
@Entity(primaryKeys = {"playlistId", "songId"})
public class PlaylistSongCrossRef {
public long playlistId;
public long songId;
}
首先,請按照平常的方法,使用資料類別和 @Relation
註解,為資料集內的兩個資料表建立關係模型。以下範例顯示的 PlaylistWithSongs
類別能夠建立 Playlist
實體類別與 Song
實體類別之間的多對多關係模型:
Kotlin
data class PlaylistWithSongs(
@Embedded val playlist: Playlist,
@Relation(
parentColumn = "playlistId",
entityColumn = "songId",
associateBy = Junction(PlaylistSongCrossRef::class)
)
val songs: List<Song>
)
Java
public class PlaylistWithSongs {
@Embedded public Playlist playlist;
@Relation(
parentColumn = "playlistId",
entityColumn = "songId",
associateBy = Junction(PlaylistSongCrossRef.class)
)
public List<Song> songs;
}
定義代表這個關係的資料類別後,請建立另一個資料類別,為資料集中的另一個資料表和第一個關係類別建立關係模型,也就是在新關係內建立「巢狀結構」的現有關係。以下範例顯示的 UserWithPlaylistsAndSongs
類別能夠建立 User
實體類別和 PlaylistWithSongs
關係類別之間的一對多關係模型:
Kotlin
data class UserWithPlaylistsAndSongs(
@Embedded val user: User
@Relation(
entity = Playlist::class,
parentColumn = "userId",
entityColumn = "userCreatorId"
)
val playlists: List<PlaylistWithSongs>
)
Java
public class UserWithPlaylistsAndSongs {
@Embedded public User user;
@Relation(
entity = Playlist.class,
parentColumn = "userId",
entityColumn = "userCreatorId"
)
public List<PlaylistWithSongs> playlists;
}
UserWithPlaylistsAndSongs
類別間接建立 User
、Playlist
和 Song
這三種實體類別之間的關係模型,如圖 1 所示。
如果資料集中還有更多資料表,請建立類別來為每個剩餘的資料表與關係類別之間建立關係模型,而該關係類別會在所有先前資料表之間建立關係模型。這項操作會在您要查詢的所有資料表之間建立巢狀結構關係鏈結。
最後,在 DAO 類別中新增方法,以顯示應用程式所需的查詢函式。此方法會要求 Room 執行多項查詢,因此請在此方法中加入 @Transaction
註解,讓整個作業以不可中斷的方式執行:
Kotlin
@Transaction
@Query("SELECT * FROM User")
fun getUsersWithPlaylistsAndSongs(): List<UserWithPlaylistsAndSongs>
Java
@Transaction
@Query("SELECT * FROM User")
public List<UserWithPlaylistsAndSongs> getUsersWithPlaylistsAndSongs();