İki öğe arasındaki çok-çok ilişkisi, ana öğenin her örneğinin alt öğenin sıfır veya daha fazla örneğine karşılık geldiği ve bunun tersi de geçerli olan bir ilişkidir.
Müzik akış uygulaması örneğinde, kullanıcı tanımlı oynatma listelerindeki şarkıları düşünün. Her oynatma listesi birçok şarkı içerebilir ve her şarkı birçok farklı oynatma listesinin parçası olabilir. Bu nedenle, Playlist
öğesi ile Song
öğesi arasında çoklu-çoklu ilişki vardır.
Veritabanınıza çoklu-çoklu ilişkileri tanımlamak ve sorgulamak için aşağıdaki adımları uygulayın:
- İlişkiyi tanımlayın: Çoklu-çoklu ilişkiyi temsil etmek için öğeleri ve ilişkilendirme öğesini (çapraz referans tablosu) oluşturun.
- Öğeleri sorgulayın: İlgili öğeleri nasıl sorgulamak istediğinizi belirleyin ve istenen çıkışı temsil edecek veri sınıfları oluşturun.
İlişkiyi tanımlama
Çoklu-çoklu ilişki tanımlamak için önce iki öğenizin her biri için bir sınıf oluşturun. Çoğunlukla alt öğede üst öğeye referans verilmediğinden, çoklu ilişki diğer ilişki türlerinden farklıdır. Bunun yerine, iki öğe arasındaki ilişkilendirme öğesini veya çapraz referans tablosunu temsil eden üçüncü bir sınıf oluşturun.
Çapraz referans tablosunda, tabloda temsil edilen çoklu ilişkideki her öğenin 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 listesine dahil edildiği bir Playlist
örneği ve Song
örneğinin eşlemesine 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ı sorgulayın
Sonraki adım, bu ilgili öğeleri nasıl sorgulamak istediğinize bağlıdır.
- Şarkı listelerini ve her şarkı listesinin karşılık gelen şarkılarının listesini sorgulamak istiyorsanız tek bir
Playlist
nesnesi ve şarkı listesinin içerdiği tümSong
nesnelerinin listesini içeren yeni bir veri sınıfı oluşturun. - Şarkıları ve her şarkıya karşılık gelen oynatma listelerinin listesini sorgulamak istiyorsanız tek bir
Song
nesnesi ve şarkının dahil edildiği tümPlaylist
nesnelerinin 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
ek açıklamaları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 göstermek için DAO sınıfına bir yöntem ekleyin.
getPlaylistsWithSongs
: Bu yöntem veritabanını sorgular ve elde edilen tümPlaylistWithSongs
nesnelerini döndürür.getSongsWithPlaylists
: Bu yöntem veritabanını sorgular ve elde edilen tümSongWithPlaylists
nesnelerini döndürür.
Bu yöntemlerin her biri Room'un iki sorgu çalıştırmasını gerektirir. Bu nedenle, işlemin tamamının 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();