ความสัมพันธ์แบบหลายต่อหลายระหว่างเอนทิตี 2 รายการคือความสัมพันธ์ที่อินสแตนซ์แต่ละรายการของเอนทิตีหลักสอดคล้องกับอินสแตนซ์ของเอนทิตีย่อยตั้งแต่ 0 รายการขึ้นไป และในทางกลับกัน
ในตัวอย่างแอปสตรีมมิงเพลง ให้พิจารณาเพลงในเพลย์ลิสต์ที่ผู้ใช้กำหนด เพลย์ลิสต์แต่ละรายการอาจมีเพลงหลายเพลง และแต่ละเพลงอาจเป็นส่วนหนึ่งของเพลย์ลิสต์หลายรายการ ดังนั้นจึงมีความสัมพันธ์แบบหลายต่อหลายระหว่างเอนทิตี Playlist
กับเอนทิตี Song
ทําตามขั้นตอนต่อไปนี้เพื่อกําหนดและค้นหาความสัมพันธ์แบบหลายต่อหลายรายการในฐานข้อมูล
- กำหนดความสัมพันธ์: สร้างเอนทิตีและเอนทิตีที่เชื่อมโยง (ตารางอ้างอิงครอส) เพื่อแสดงความสัมพันธ์แบบหลายต่อหลาย
- ค้นหาเอนทิตี: กำหนดวิธีค้นหาเอนทิตีที่เกี่ยวข้องและสร้างคลาสข้อมูลเพื่อแสดงผลลัพธ์ที่ต้องการ
กําหนดความสัมพันธ์
หากต้องการกำหนดความสัมพันธ์แบบหลายต่อหลายรายการ ให้สร้างคลาสสำหรับเอนทิตีแต่ละรายการก่อน ความสัมพันธ์แบบหลายต่อหลายรายการแตกต่างจากความสัมพันธ์ประเภทอื่นๆ เนื่องจากโดยทั่วไปแล้วจะไม่มีการอ้างอิงถึงเอนทิตีหลักในเอนทิตีย่อย แต่ให้สร้างคลาสที่ 3 เพื่อแสดงเอนทิตีที่เชื่อมโยงหรือตารางอ้างอิงไขว้ระหว่างเอนทิตี 2 รายการแทน
ตารางอ้างอิงต้องมีคอลัมน์สำหรับคีย์หลักจากเอนทิตีแต่ละรายการในความสัมพันธ์แบบหลายต่อหลายที่แสดงในตาราง ในตัวอย่างนี้ แต่ละแถวในตารางการอ้างอิงจะสอดคล้องกับการจับคู่อินสแตนซ์ Playlist
กับอินสแตนซ์ Song
ที่รวมเพลงที่อ้างอิงในเพลย์ลิสต์ที่อ้างอิง
Kotlin
@Entity
data class Playlist(
@PrimaryKey val playlistId: 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 Playlist {
@PrimaryKey public long playlistId;
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;
}
ค้นหาเอนทิตี
ขั้นตอนถัดไปขึ้นอยู่กับวิธีที่คุณต้องการค้นหาเอนทิตีที่เกี่ยวข้องเหล่านี้
- หากต้องการค้นหาเพลย์ลิสต์และรายการเพลงที่เกี่ยวข้องสำหรับแต่ละเพลย์ลิสต์ ให้สร้างคลาสข้อมูลใหม่ที่มีแออบเจ็กต์
Playlist
รายการเดียวและรายการออบเจ็กต์Song
ทั้งหมดที่เพลย์ลิสต์มี - หากต้องการค้นหาเพลงและรายการเพลย์ลิสต์ที่เกี่ยวข้องสำหรับแต่ละรายการ ให้สร้างคลาสข้อมูลใหม่ที่ประกอบด้วยออบเจ็กต์
Song
รายการเดียวและรายการออบเจ็กต์Playlist
ทั้งหมดที่มีเพลงนั้นๆ รวมอยู่ด้วย
ไม่ว่าในกรณีใด ให้สร้างรูปแบบความสัมพันธ์ระหว่างเอนทิตีโดยใช้พร็อพเพอร์ตี้ associateBy
ในคำอธิบายประกอบ @Relation
ในแต่ละคลาสเหล่านี้เพื่อระบุเอนทิตีการอ้างอิงซึ่งระบุความสัมพันธ์ระหว่างเอนทิตี Playlist
กับเอนทิตี Song
Kotlin
data class PlaylistWithSongs(
@Embedded val playlist: Playlist,
@Relation(
parentColumn = "playlistId",
entityColumn = "songId",
associateBy = Junction(PlaylistSongCrossRef::class)
)
val songs: List<Song>
)
data class SongWithPlaylists(
@Embedded val song: Song,
@Relation(
parentColumn = "songId",
entityColumn = "playlistId",
associateBy = Junction(PlaylistSongCrossRef::class)
)
val playlists: List<Playlist>
)
Java
public class PlaylistWithSongs {
@Embedded public Playlist playlist;
@Relation(
parentColumn = "playlistId",
entityColumn = "songId",
associateBy = @Junction(PlaylistSongCrossref.class)
)
public List<Song> songs;
}
public class SongWithPlaylists {
@Embedded public Song song;
@Relation(
parentColumn = "songId",
entityColumn = "playlistId",
associateBy = @Junction(PlaylistSongCrossref.class)
)
public List<Playlist> playlists;
}
สุดท้าย ให้เพิ่มเมธอดลงในคลาส DAO เพื่อแสดงฟังก์ชันการค้นหาที่แอปของคุณต้องการ
getPlaylistsWithSongs
: เมธอดนี้จะค้นหาฐานข้อมูลและแสดงผลออบเจ็กต์PlaylistWithSongs
ทั้งหมดgetSongsWithPlaylists
: เมธอดนี้จะค้นหาฐานข้อมูลและแสดงผลออบเจ็กต์SongWithPlaylists
ทั้งหมด
แต่ละเมธอดเหล่านี้กำหนดให้ Room เรียกใช้การค้นหา 2 ครั้ง ดังนั้นให้เพิ่มคำอธิบายประกอบ @Transaction
ลงในทั้ง 2 เมธอดเพื่อให้การดำเนินการทั้งหมดทำงานแบบอะตอม
Kotlin
@Transaction
@Query("SELECT * FROM Playlist")
fun getPlaylistsWithSongs(): List<PlaylistWithSongs>
@Transaction
@Query("SELECT * FROM Song")
fun getSongsWithPlaylists(): List<SongWithPlaylists>
Java
@Transaction
@Query("SELECT * FROM Playlist")
public List<PlaylistWithSongs> getPlaylistsWithSongs();
@Transaction
@Query("SELECT * FROM Song")
public List<SongWithPlaylists> getSongsWithPlaylists();