Koleksiyonlar ile düzeninizi koruyun
İçeriği tercihlerinize göre kaydedin ve kategorilere ayırın.
İ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.
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.
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ı sorgular ve 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")fungetPlaylistsWithSongs():List<PlaylistWithSongs>@Transaction@Query("SELECT * FROM Song")fungetSongsWithPlaylists():List<SongWithPlaylists>
Java
@Transaction@Query("SELECT * FROM Playlist")publicList<PlaylistWithSongs>getPlaylistsWithSongs();@Transaction@Query("SELECT * FROM Song")publicList<SongWithPlaylists>getSongsWithPlaylists();
Bu sayfadaki içerik ve kod örnekleri, İçerik Lisansı sayfasında açıklanan lisanslara tabidir. Java ve OpenJDK, Oracle ve/veya satış ortaklarının tescilli ticari markasıdır.
Son güncelleme tarihi: 2025-07-27 UTC.
[[["Anlaması kolay","easyToUnderstand","thumb-up"],["Sorunumu çözdü","solvedMyProblem","thumb-up"],["Diğer","otherUp","thumb-up"]],[["İhtiyacım olan bilgiler yok","missingTheInformationINeed","thumb-down"],["Çok karmaşık / çok fazla adım var","tooComplicatedTooManySteps","thumb-down"],["Güncel değil","outOfDate","thumb-down"],["Çeviri sorunu","translationIssue","thumb-down"],["Örnek veya kod sorunu","samplesCodeIssue","thumb-down"],["Diğer","otherDown","thumb-down"]],["Son güncelleme tarihi: 2025-07-27 UTC."],[],[],null,["# Define and query many-to-many relationships\n\nA *many-to-many relationship* between two entities is a relationship where each\ninstance of the parent entity corresponds to zero or more instances of the child\nentity, and the reverse is also true.\n\nIn the music streaming app example, consider the songs in the user-defined\nplaylists. Each playlist can include many songs, and each song can be a part of\nmany different playlists. Therefore, there is a many-to-many relationship\nbetween the `Playlist` entity and the `Song` entity.\n\nFollow these steps to define and query many-to-many relationships in your\ndatabase:\n\n1. **[Define the relationship](#define)**: Establish the entities and the associative entity (cross-reference table) to represent the many-to-many relationship.\n2. **[Query the entities](#query)**: Determine how you want to query the related entities and create data classes to represent the intended output.\n\nDefine the relationship\n-----------------------\n\nTo define a many-to-many relationship, first create a class for each of your two\nentities. Many-to-many relationships are distinct from other relationship types\nbecause there is generally no reference to the parent entity in the child\nentity. Instead, create a third class to represent an [associative\nentity](https://en.wikipedia.org/wiki/Associative_entity), or *cross-reference table* , between the two entities.\nThe cross-reference table must have columns for the primary key from each entity\nin the many-to-many relationship represented in the table. In this example, each\nrow in the cross-reference table corresponds to a pairing of a `Playlist`\ninstance and a `Song` instance where the referenced song is included in the\nreferenced playlist. \n\n### Kotlin\n\n @Entity\n data class Playlist(\n @PrimaryKey val playlistId: Long,\n val playlistName: String\n )\n\n @Entity\n data class Song(\n @PrimaryKey val songId: Long,\n val songName: String,\n val artist: String\n )\n\n @Entity(primaryKeys = [\"playlistId\", \"songId\"])\n data class PlaylistSongCrossRef(\n val playlistId: Long,\n val songId: Long\n )\n\n### Java\n\n @Entity\n public class Playlist {\n @PrimaryKey public long playlistId;\n public String playlistName;\n }\n\n @Entity\n public class Song {\n @PrimaryKey public long songId;\n public String songName;\n public String artist;\n }\n\n @Entity(primaryKeys = {\"playlistId\", \"songId\"})\n public class PlaylistSongCrossRef {\n public long playlistId;\n public long songId;\n }\n\nQuery the entities\n------------------\n\nThe next step depends on how you want to query these related entities.\n\n- If you want to query *playlists* and a list of the corresponding *songs* for each playlist, create a new data class that contains a single `Playlist` object and a list of all of the `Song` objects that the playlist includes.\n- If you want to query *songs* and a list of the corresponding *playlists* for each, create a new data class that contains a single `Song` object and a list of all of the `Playlist` objects in which the song is included.\n\nIn either case, model the relationship between the entities by using the\n[`associateBy`](/reference/kotlin/androidx/room/Relation#associateBy()) property in the [`@Relation`](/reference/kotlin/androidx/room/Relation) annotation in each of these\nclasses to identify the cross-reference entity providing the relationship\nbetween the `Playlist` entity and the `Song` entity. \n\n### Kotlin\n\n data class PlaylistWithSongs(\n @Embedded val playlist: Playlist,\n @Relation(\n parentColumn = \"playlistId\",\n entityColumn = \"songId\",\n associateBy = Junction(PlaylistSongCrossRef::class)\n )\n val songs: List\u003cSong\u003e\n )\n\n data class SongWithPlaylists(\n @Embedded val song: Song,\n @Relation(\n parentColumn = \"songId\",\n entityColumn = \"playlistId\",\n associateBy = Junction(PlaylistSongCrossRef::class)\n )\n val playlists: List\u003cPlaylist\u003e\n )\n\n### Java\n\n public class PlaylistWithSongs {\n @Embedded public Playlist playlist;\n @Relation(\n parentColumn = \"playlistId\",\n entityColumn = \"songId\",\n associateBy = @Junction(PlaylistSongCrossref.class)\n )\n public List\u003cSong\u003e songs;\n }\n\n public class SongWithPlaylists {\n @Embedded public Song song;\n @Relation(\n parentColumn = \"songId\",\n entityColumn = \"playlistId\",\n associateBy = @Junction(PlaylistSongCrossref.class)\n )\n public List\u003cPlaylist\u003e playlists;\n }\n\nFinally, add a method to the DAO class to expose the query function your\napp needs.\n\n- `getPlaylistsWithSongs`: this method queries the database and returns all the resulting `PlaylistWithSongs` objects.\n- `getSongsWithPlaylists`: this method queries the database and returns all the resulting `SongWithPlaylists` objects.\n\nThese methods each require Room to run two queries, so add the\n[`@Transaction`](/reference/kotlin/androidx/room/Transaction) annotation to both methods so that the whole\noperation is performed atomically. \n\n### Kotlin\n\n @Transaction\n @Query(\"SELECT * FROM Playlist\")\n fun getPlaylistsWithSongs(): List\u003cPlaylistWithSongs\u003e\n\n @Transaction\n @Query(\"SELECT * FROM Song\")\n fun getSongsWithPlaylists(): List\u003cSongWithPlaylists\u003e\n\n### Java\n\n @Transaction\n @Query(\"SELECT * FROM Playlist\")\n public List\u003cPlaylistWithSongs\u003e getPlaylistsWithSongs();\n\n @Transaction\n @Query(\"SELECT * FROM Song\")\n public List\u003cSongWithPlaylists\u003e getSongsWithPlaylists();\n\n| **Note:** If the `@Relation` annotation does not meet your specific use case, you might need to use the `JOIN` keyword in your SQL queries to manually define the appropriate relationships. To learn more about querying multiple tables manually, read [Accessing data using Room\n| DAOs](/training/data-storage/room/accessing-data#query-multiple-tables)."]]