เนื่องจาก SQLite เป็นฐานข้อมูลเชิงสัมพันธ์ คุณจึงสามารถกำหนดความสัมพันธ์ระหว่าง เอนทิตี แต่ในขณะที่ไลบรารีการแมปวัตถุเชิงสัมพันธ์ส่วนใหญ่อนุญาตให้เอนทิตี วัตถุอ้างอิงถึงกัน แต่ Room จะห้ามอย่างชัดแจ้ง เพื่อเรียนรู้เกี่ยวกับ เหตุผลทางเทคนิคเบื้องหลังการตัดสินใจนี้ โปรดดูทําความเข้าใจสาเหตุที่ห้องแชทไม่ อนุญาตการอ้างอิงออบเจ็กต์
2 วิธีที่เป็นไปได้
กําหนดและค้นหาความสัมพันธ์ระหว่างเอนทิตีในห้องแชทได้ 2 วิธี ดังนี้ ที่ใช้คลาสข้อมูลระดับกลางกับ ออบเจ็กต์ที่ฝังหรือวิธีการค้นหาเชิงสัมพันธ์ที่มีการส่งคืนมัลติแมป ประเภท
คลาสข้อมูลระดับกลาง
ในแนวทางคลาสข้อมูลระดับกลาง คุณจะกำหนดคลาสข้อมูลที่สร้างโมเดล ความสัมพันธ์ระหว่างเอนทิตีห้องพัก คลาสข้อมูลนี้มีการจับคู่ ระหว่างอินสแตนซ์ของเอนทิตีหนึ่ง และอินสแตนซ์ของเอนทิตีอื่นเป็น แบบฝัง ออบเจ็กต์ จากนั้นเมธอดการค้นหาสามารถแสดงอินสแตนซ์ของรายการนี้ คลาสข้อมูลมาใช้ในแอปด้วย
เช่น คุณกำหนดคลาสข้อมูล UserBook
เพื่อแสดงถึงผู้ใช้ห้องสมุดได้
หนังสือบางเล่มที่เช็คเอาต์ และกำหนดวิธีการสืบค้นเพื่อเรียกดูรายการ
UserBook
อินสแตนซ์จากฐานข้อมูล:
Kotlin
@Dao interface UserBookDao { @Query( "SELECT user.name AS userName, book.name AS bookName " + "FROM user, book " + "WHERE user.id = book.user_id" ) fun loadUserAndBookNames(): LiveData<List<UserBook>> } data class UserBook(val userName: String?, val bookName: String?)
Java
@Dao public interface UserBookDao { @Query("SELECT user.name AS userName, book.name AS bookName " + "FROM user, book " + "WHERE user.id = book.user_id") public LiveData<List<UserBook>> loadUserAndBookNames(); } public class UserBook { public String userName; public String bookName; }
ประเภทการแสดงผลแบบหลายแมป
ในแนวทางประเภทการคืนสินค้าแบบหลายแมป คุณไม่จำเป็นต้องระบุเพิ่มเติม คลาสข้อมูล แต่คุณจะกําหนด multimap ผลลัพธ์ประเภทสำหรับ ของคุณตามโครงสร้างแผนที่ที่คุณต้องการและกำหนดความสัมพันธ์ ระหว่างเอนทิตีได้โดยตรงในคำสั่ง SQL
ตัวอย่างเช่น วิธีการค้นหาต่อไปนี้จะแสดงการแมป User
และ Book
อินสแตนซ์เพื่อเป็นตัวแทนผู้ใช้ห้องสมุดที่มีหนังสือบางเล่มที่ชำระเงินแล้ว:
Kotlin
@Query( "SELECT * FROM user" + "JOIN book ON user.id = book.user_id" ) fun loadUserAndBookNames(): Map<User, List<Book>>
Java
@Query( "SELECT * FROM user" + "JOIN book ON user.id = book.user_id" ) public Map<User, List<Book>> loadUserAndBookNames();
เลือกวิธีการ
Room รองรับทั้ง 2 วิธีนี้ คุณจึงใช้ แล้วแต่ว่าวิธีการใดจะเหมาะกับแอปของคุณมากที่สุด ส่วนนี้จะอธิบายเกี่ยวกับ เหตุผลว่าทำไมคุณจึงน่าจะชอบอย่างใดอย่างหนึ่ง
แนวทางคลาสข้อมูลระดับกลางช่วยให้คุณไม่ต้องเขียน SQL ที่ซับซ้อน แต่อาจส่งผลให้โค้ดมีความซับซ้อนยิ่งขึ้นเนื่องจาก คลาสข้อมูลเพิ่มเติมที่จำเป็นต้องใช้ กล่าวโดยสรุปคือ ประเภทผลตอบแทนแบบหลายแผนที่ วิธีนี้ต้องใช้การค้นหา SQL เพื่อให้ทำงานได้มากขึ้น และข้อมูลสื่อกลาง แนวทางของชั้นเรียนต้องใช้โค้ดในการทำงานเพิ่มเติม
หากคุณไม่มีเหตุผลเฉพาะเจาะจงที่จะใช้คลาสข้อมูลระดับกลาง แนะนำให้ใช้ประเภทผลตอบแทนแบบหลายแผนที่ หากต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับ ด้วยวิธีนี้ โปรดดูส่งคืน มัลติแมป
ส่วนที่เหลือของคู่มือนี้จะสาธิตวิธีการกำหนดความสัมพันธ์โดยใช้ ข้อมูลระดับกลาง
สร้างวัตถุที่ฝัง
บางครั้งคุณต้องการแสดงเอนทิตีหรือออบเจ็กต์ข้อมูลเป็น
สอดคล้องกันทั้งหมดในตรรกะฐานข้อมูล แม้ว่าออบเจ็กต์นั้นจะมี
ด้วย ในกรณีเหล่านี้ คุณสามารถใช้
@Embedded
สำหรับแทนวัตถุที่คุณต้องการแยกย่อย
ช่องย่อยภายในตาราง จากนั้น คุณสามารถค้นหาช่องที่ฝังได้เช่นเดียวกับที่คุณค้นหา
สำหรับคอลัมน์อื่นๆ แต่ละคอลัมน์
ตัวอย่างเช่น ชั้นเรียน User
จะมีช่องประเภท Address
ที่
แสดงองค์ประกอบของช่องชื่อ street
, city
, state
และ
postCode
หากต้องการจัดเก็บคอลัมน์ที่เขียนไว้ต่างหากในตาราง ให้ใส่
Address
ในคลาส User
ที่มีคำอธิบายประกอบ
@Embedded
, ในฐานะ
ที่แสดงในข้อมูลโค้ดต่อไปนี้
Kotlin
data class Address( val street: String?, val state: String?, val city: String?, @ColumnInfo(name = "post_code") val postCode: Int ) @Entity data class User( @PrimaryKey val id: Int, val firstName: String?, @Embedded val address: Address? )
Java
public class Address { public String street; public String state; public String city; @ColumnInfo(name = "post_code") public int postCode; } @Entity public class User { @PrimaryKey public int id; public String firstName; @Embedded public Address address; }
ตารางที่แสดงออบเจ็กต์ User
จะมีคอลัมน์ที่มีข้อมูลต่อไปนี้
ชื่อ: id
, firstName
, street
, state
, city
และ post_code
หากเอนทิตีมีช่องประเภทเดียวกันที่ฝังอยู่หลายช่อง คุณสามารถเก็บแต่ละช่องไว้
ไม่ซ้ำกัน โดยการตั้งค่า
prefix
จากนั้นห้องแชทจะเพิ่มค่าที่ระบุลงในส่วนต้นของแต่ละคอลัมน์
ในออบเจ็กต์ที่ฝัง
กำหนดความสัมพันธ์แบบหนึ่งต่อหนึ่ง
ความสัมพันธ์แบบหนึ่งต่อหนึ่งระหว่าง 2 เอนทิตีคือความสัมพันธ์ที่แต่ละเอนทิตี อินสแตนซ์ของเอนทิตีหลักสอดคล้องกับอินสแตนซ์ของเอนทิตีย่อยเพียง 1 รายการ และรายการในทางกลับกันก็เป็นจริงเช่นกัน
ตัวอย่างเช่น ลองพิจารณาแอปสตรีมมิงเพลงที่ผู้ใช้มีคลัง
เพลงที่ตนเป็นเจ้าของ ผู้ใช้แต่ละรายจะมีไลบรารีเพียง 1 รายการ และแต่ละไลบรารี
ตรงกับผู้ใช้ 1 คนเท่านั้น ดังนั้นจึงมีรูปแบบ 1 ต่อ 1
ความสัมพันธ์ระหว่างเอนทิตี User
และเอนทิตี Library
หากต้องการกำหนดความสัมพันธ์แบบหนึ่งต่อหนึ่ง ให้สร้างคลาสสำหรับทั้งสองกลุ่มก่อน เอนทิตี หนึ่งในเอนทิตีต้อง รวมตัวแปรที่เป็นการอ้างอิงไปยังคีย์หลักของเอนทิตีอื่น
Kotlin
@Entity data class User( @PrimaryKey val userId: Long, val name: String, val age: Int ) @Entity data class Library( @PrimaryKey val libraryId: Long, val userOwnerId: Long )
Java
@Entity public class User { @PrimaryKey public long userId; public String name; public int age; } @Entity public class Library { @PrimaryKey public long libraryId; public long userOwnerId; }
หากต้องการค้นหารายชื่อผู้ใช้และไลบรารีที่เกี่ยวข้อง ก่อนอื่นคุณต้อง
สร้างความสัมพันธ์แบบหนึ่งต่อหนึ่งระหว่าง 2 เอนทิตี ในการดำเนินการนี้ ให้สร้าง
คลาสข้อมูลใหม่ที่แต่ละอินสแตนซ์มีอินสแตนซ์ของเอนทิตีระดับบนและ
อินสแตนซ์ที่เกี่ยวข้องของเอนทิตีย่อย เพิ่ม @Relation
คำอธิบายประกอบให้กับอินสแตนซ์ของเอนทิตีย่อย โดยตั้งค่า parentColumn
เป็น
ชื่อของคอลัมน์คีย์หลักของเอนทิตีระดับบนสุดและ entityColumn
ตั้งค่าเป็นชื่อของคอลัมน์ของเอนทิตีย่อยที่อ้างอิงระดับบนสุด
คีย์หลักของเอนทิตี
Kotlin
data class UserAndLibrary( @Embedded val user: User, @Relation( parentColumn = "userId", entityColumn = "userOwnerId" ) val library: Library )
Java
public class UserAndLibrary { @Embedded public User user; @Relation( parentColumn = "userId", entityColumn = "userOwnerId" ) public Library library; }
สุดท้าย เพิ่มเมธอดลงในคลาส DAO ที่ส่งคืนอินสแตนซ์ทั้งหมดของข้อมูล
ที่จับคู่เอนทิตีหลักและเอนทิตีย่อย วิธีนี้ต้องใช้
พื้นที่สำหรับเรียกใช้การค้นหา 2 รายการ ดังนั้นให้เพิ่มคำอธิบายประกอบ @Transaction
ลงในส่วนนี้
เพื่อให้การดำเนินการทั้งหมดทำงานในแบบอะตอม
Kotlin
@Transaction @Query("SELECT * FROM User") fun getUsersAndLibraries(): List<UserAndLibrary>
Java
@Transaction @Query("SELECT * FROM User") public List<UserAndLibrary> getUsersAndLibraries();
กำหนดความสัมพันธ์แบบ 1 ต่อหลายรายการ
ความสัมพันธ์แบบหนึ่งต่อหลายระหว่าง 2 เอนทิตีคือความสัมพันธ์ที่แต่ละเอนทิตี อินสแตนซ์ของเอนทิตีหลักสอดคล้องกับอินสแตนซ์ของหน่วยย่อยเป็นศูนย์หรือมากกว่า แต่เอนทิตีย่อยแต่ละรายการสามารถเชื่อมโยงกับได้เพียงรายการเดียวเท่านั้น ของเอนทิตีหลัก
ในตัวอย่างแอปสตรีมมิงเพลง สมมติว่าผู้ใช้มีความสามารถในการจัดระเบียบ
เพลงลงในเพลย์ลิสต์ ผู้ใช้แต่ละคนสามารถสร้างเพลย์ลิสต์
ได้มากเท่าที่ต้องการ
แต่เพลย์ลิสต์แต่ละรายการสร้างขึ้นโดยผู้ใช้ 1 คน ดังนั้นจึงมี
ความสัมพันธ์แบบหนึ่งต่อหลายรายการระหว่างเอนทิตี User
และเอนทิตี Playlist
หากต้องการกำหนดความสัมพันธ์แบบหนึ่งต่อหลายรายการ ให้สร้างคลาสสำหรับทั้งสองเอนทิตีก่อน ในความสัมพันธ์แบบหนึ่งต่อหนึ่ง เอนทิตีลูกจะต้องรวมตัวแปรที่ เป็นการอ้างอิงไปยังคีย์หลักของเอนทิตีระดับบน
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 )
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; }
หากต้องการค้นหารายชื่อผู้ใช้และเพลย์ลิสต์ที่เกี่ยวข้อง ก่อนอื่นคุณต้อง
จำลองความสัมพันธ์แบบ 1 ต่อหลายรายการระหว่าง 2 เอนทิตี ในการดำเนินการนี้ ให้สร้าง
คลาสข้อมูลใหม่ซึ่งแต่ละอินสแตนซ์จะมีอินสแตนซ์ของเอนทิตีระดับบน
รายการของอินสแตนซ์เอนทิตีย่อยที่เกี่ยวข้องทั้งหมด เพิ่ม @Relation
คำอธิบายประกอบให้กับอินสแตนซ์ของเอนทิตีย่อย โดยตั้งค่า parentColumn
เป็น
ชื่อของคอลัมน์คีย์หลักของเอนทิตีระดับบนสุดและ entityColumn
ตั้งค่าเป็นชื่อของคอลัมน์ของเอนทิตีย่อยที่อ้างอิงระดับบนสุด
คีย์หลักของเอนทิตี
Kotlin
data class UserWithPlaylists( @Embedded val user: User, @Relation( parentColumn = "userId", entityColumn = "userCreatorId" ) val playlists: List<Playlist> )
Java
public class UserWithPlaylists { @Embedded public User user; @Relation( parentColumn = "userId", entityColumn = "userCreatorId" ) public List<Playlist> playlists; }
สุดท้าย เพิ่มเมธอดลงในคลาส DAO ที่ส่งคืนอินสแตนซ์ทั้งหมดของข้อมูล
ที่จับคู่เอนทิตีหลักและเอนทิตีย่อย วิธีนี้ต้องใช้
พื้นที่สำหรับเรียกใช้การค้นหา 2 รายการ ดังนั้นให้เพิ่มคำอธิบายประกอบ @Transaction
ลงในส่วนนี้
เพื่อให้การดำเนินการทั้งหมดทำงานในแบบอะตอม
Kotlin
@Transaction @Query("SELECT * FROM User") fun getUsersWithPlaylists(): List<UserWithPlaylists>
Java
@Transaction @Query("SELECT * FROM User") public List<UserWithPlaylists> getUsersWithPlaylists();
กำหนดความสัมพันธ์แบบหลายต่อหลาย
ความสัมพันธ์แบบหลายต่อหลายระหว่าง 2 เอนทิตีคือความสัมพันธ์ที่แต่ละเอนทิตี อินสแตนซ์ของเอนทิตีหลักสอดคล้องกับอินสแตนซ์ของหน่วยย่อยเป็นศูนย์หรือมากกว่า และรายการในทางกลับกันก็เป็นจริงเช่นกัน
ในตัวอย่างแอปสตรีมมิงเพลง ให้พิจารณาเพลงในเพลย์ลิสต์ที่ผู้ใช้กำหนด
แต่ละเพลย์ลิสต์อาจมีเพลงได้หลายเพลง ซึ่งแต่ละเพลงอาจเป็นส่วนหนึ่ง
เพลย์ลิสต์ต่างๆ ดังนั้นจึงมีความสัมพันธ์แบบหลายต่อหลาย
ระหว่างเอนทิตี Playlist
และเอนทิตี Song
หากต้องการกำหนดความสัมพันธ์แบบหลายต่อหลายรายการ ให้สร้างคลาสสำหรับความสัมพันธ์แบบหลายต่อหลายรายการก่อน
เอนทิตี ความสัมพันธ์แบบหลายต่อหลาย
จะแตกต่างจากความสัมพันธ์ประเภทอื่นๆ เนื่องจากโดยทั่วไปแล้ว
การอ้างอิงไปยังเอนทิตีหลักในเอนทิตีย่อย ให้สร้าง
เพื่อแสดงถึงหน่วยงานที่เชื่อมโยงหรือเปรียบเทียบระหว่างบุคคล
ตารางระหว่าง 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
ออบเจ็กต์
วิธีการเหล่านี้ต้องมีห้องแชทเพื่อเรียกใช้การค้นหา 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();
กำหนดความสัมพันธ์ที่ซ้อนกัน
บางครั้งคุณอาจต้องค้นหาชุดตารางตั้งแต่ 3 ตารางขึ้นไป ที่เกี่ยวข้องกัน ในกรณีดังกล่าว คุณจะต้องกำหนดความสัมพันธ์ที่ซ้อนกัน ระหว่างตารางได้
สมมติว่าในตัวอย่างแอปสตรีมมิงเพลง คุณต้องการค้นหา เพลย์ลิสต์ทั้งหมดของผู้ใช้แต่ละราย และเพลงทั้งหมดในเพลย์ลิสต์แต่ละรายการ สำหรับผู้ใช้แต่ละคน ผู้ใช้ที่มีความสัมพันธ์แบบหนึ่งต่อหลายคนกับ เพลย์ลิสต์ และเพลย์ลิสต์มีความสัมพันธ์แบบหลายต่อหลาย เพลง ตัวอย่างโค้ดต่อไปนี้แสดงคลาสที่แสดงถึง รวมทั้งตารางเปรียบเทียบข้อมูลสำหรับความสัมพันธ์แบบหลายต่อหลายรายการ ระหว่างเพลย์ลิสต์และเพลง
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; }
ขั้นแรก จำลองความสัมพันธ์ระหว่าง 2 ตารางในชุดขณะที่คุณ
โดยใช้คลาสข้อมูลและฟังก์ชัน
@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
ที่โมเดล
ความสัมพันธ์แบบ 1 ต่อหลายรายการระหว่างคลาสเอนทิตี 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
สร้างโมเดลความสัมพันธ์โดยอ้อม
ระหว่างคลาสเอนทิตีทั้ง 3 รายการ ได้แก่ User
, Playlist
และ Song
นี่คือ
ตามที่แสดงในรูปที่ 1
![UserWithAssignmentsAndSongs สร้างโมเดลความสัมพันธ์ระหว่างผู้ใช้กับ
เพลย์ลิสต์WithSongs ซึ่งจะเชื่อมโยงความสัมพันธ์ระหว่างเพลย์ลิสต์
และเพลง](https://developer.android.com/static/images/training/data-storage/room_nested_relationships.png?authuser=4&hl=th)
รูปที่ 1 แผนภาพของคลาสความสัมพันธ์ใน ตัวอย่างแอปสตรีมมิงเพลง
หากมีตารางอื่นๆ ในชุด ให้สร้างคลาสเพื่อสร้างโมเดล ความสัมพันธ์ระหว่างแต่ละตารางที่เหลือและคลาสความสัมพันธ์ที่จำลองแบบ ความสัมพันธ์ระหว่างตารางก่อนหน้าทั้งหมด สิ่งนี้จะสร้างห่วงโซ่ของ ในตารางทั้งหมดที่คุณต้องการค้นหา
สุดท้าย เพิ่มเมธอดลงในคลาส DAO เพื่อแสดงฟังก์ชันการค้นหาที่
ที่แอปของคุณต้องใช้ วิธีนี้ต้องใช้ห้องแชทเพื่อเรียกใช้การค้นหาหลายรายการ ดังนั้นให้เพิ่ม
คำอธิบายประกอบ @Transaction
เพื่อให้การดำเนินการทั้งหมดทำงานได้ในระดับอะตอม:
Kotlin
@Transaction @Query("SELECT * FROM User") fun getUsersWithPlaylistsAndSongs(): List<UserWithPlaylistsAndSongs>
Java
@Transaction @Query("SELECT * FROM User") public List<UserWithPlaylistsAndSongs> getUsersWithPlaylistsAndSongs();
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดความสัมพันธ์ระหว่างเอนทิตีในห้องแชทได้ที่ ตามแหล่งข้อมูลเพิ่มเติมต่อไปนี้
ตัวอย่าง
วิดีโอ
- มีอะไรใหม่ในห้องแชท (Android Dev การประชุมสุดยอดปี 2019)