İki varlık arasındaki çoktan çok ilişki, ana varlığın her örneğinin sıfır veya daha fazla alt varlık örneğine karşılık geldiği ve bunun tersinin de geçerli olduğu bir ilişkidir.
Müzik akışı uygulaması örneğinde, kullanıcı tanımlı oynatma listelerindeki şarkıları göz önünde bulundurun. Her oynatma listesi birçok şarkı içerebilir ve her şarkı birçok farklı oynatma listesinde yer alabilir. Bu nedenle, Playlist öğesi ile Song öğesi arasında çoka çok ilişki vardır.
Veritabanınızdaki çoktan çok ilişkiyi tanımlamak ve sorgulamak için aşağıdaki adımları uygulayın:
- İlişkiyi tanımlayın: Çoka-çok ilişkisini temsil etmek için öğeleri ve ilişkili öğeyi (çapraz referans tablosu) oluşturun.
- Varlıkları sorgulama: İlgili varlıkları nasıl sorgulamak istediğinizi belirleyin ve amaçlanan çıktıyı temsil edecek veri sınıfları oluşturun.
İlişkiyi tanımlama
Çoktan çoğa ilişki tanımlamak için öncelikle iki varlığınızın her biri için bir sınıf oluşturun. Çoktan çoka ilişkiler, diğer ilişki türlerinden farklıdır. Çünkü genellikle alt öğede üst öğeye referans verilmez. Bunun yerine, iki öğe arasında ilişkilendirilmiş bir öğeyi veya çapraz referans tablosunu temsil eden üçüncü bir sınıf oluşturun.
Çapraz başvuru tablosunda, tabloda temsil edilen çoktan çoğa ilişkideki her varlığın birincil anahtarı için sütunlar olmalıdır. Bu örnekte, çapraz referans tablosundaki her satır, referans verilen şarkının referans verilen oynatma listesinde yer aldığı bir Playlist örneği ile bir Song örneğinin eşleşmesine karşılık gelir.
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;
}
Varlıkları sorgulama
Bir sonraki adım, bu ilgili öğeleri nasıl sorgulamak istediğinize bağlıdır.
- Oynatma listelerini ve her oynatma listesi için ilgili şarkıların listesini sorgulamak istiyorsanız tek bir
Playlistnesnesi ve oynatma listesinin içerdiği tümSongnesnelerinin listesini içeren yeni bir veri sınıfı oluşturun. - Şarkıları ve her şarkı için ilgili oynatma listelerinin listesini sorgulamak istiyorsanız tek bir
Songnesnesi ve şarkının yer aldığı tümPlaylistnesnelerinin listesini içeren yeni bir veri sınıfı oluşturun.
Her iki durumda da, Playlist öğesi ile Song öğesi arasındaki ilişkiyi sağlayan çapraz referans öğesini tanımlamak için bu sınıfların her birindeki @Relation açıklamasında associateBy özelliğini kullanarak öğeler arasındaki ilişkiyi modelleyin.
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;
}
Son olarak, uygulamanızın ihtiyaç duyduğu sorgu işlevini kullanıma sunmak için DAO sınıfına bir yöntem ekleyin.
getPlaylistsWithSongs: Bu yöntem, veritabanını sorgular ve sonuç olarak elde edilen tümPlaylistWithSongsnesnelerini döndürür.getSongsWithPlaylists: Bu yöntem, veritabanını sorgular ve sonuç olarak elde edilen tümSongWithPlaylistsnesnelerini döndürür.
Bu yöntemlerin her birinde Room'un iki sorgu çalıştırması gerekir. Bu nedenle, tüm işlemin atomik olarak gerçekleştirilmesi için her iki yönteme de @Transaction ek açıklamasını ekleyin.
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();