Çoklu-çoklu ilişkileri tanımlama ve sorgulama

İ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:

  1. İlişkiyi tanımlayın: Çoklu-çoklu ilişkiyi temsil etmek için öğeleri ve ilişkilendirme öğesini (çapraz referans tablosu) oluşturun.
  2. Öğ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-çoklu ilişkiler diğer ilişki türlerinden farklıdır. Bunun yerine, iki öğe arasındaki ilişkilendirme öğesini veya çapraz referans tablosunu temsil edecek üçü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üm Song 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üm Playlist 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üm PlaylistWithSongs nesnelerini döndürür.
  • getSongsWithPlaylists: Bu yöntem veritabanını sorgulayarak elde edilen tüm SongWithPlaylists 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();