Mit Sammlungen den Überblick behalten
Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.
Eine Mehrfachbeziehung zwischen zwei Entitäten ist eine Beziehung, bei der jeder Instanz der übergeordneten Entität null oder mehr Instanzen der untergeordneten Entität entsprechen und umgekehrt.
Denken Sie im Beispiel für die Musik-Streaming-App an die Titel in den benutzerdefinierten Playlists. Jede Playlist kann viele Titel enthalten und jeder Titel kann Teil vieler verschiedener Playlists sein. Daher besteht zwischen der Entität Playlist und der Entität Song eine m:n-Beziehung.
So definieren und abfragen Sie Beziehungen vom Typ „Mehrfach zu Mehrfach“ in Ihrer Datenbank:
Beziehung definieren: Legen Sie die Entitäten und die assoziative Entität (Verweistabelle) fest, um die m:n-Beziehung darzustellen.
Entitäten abfragen: Legen Sie fest, wie Sie die zugehörigen Entitäten abfragen möchten, und erstellen Sie Datenklassen, um die gewünschte Ausgabe darzustellen.
Beziehung definieren
Wenn Sie eine n:n-Beziehung definieren möchten, erstellen Sie zuerst eine Klasse für jede Ihrer beiden Entitäten. m:n-Beziehungen unterscheiden sich von anderen Beziehungstypen, da es in der untergeordneten Entität in der Regel keinen Verweis auf die übergeordnete Entität gibt. Erstellen Sie stattdessen eine dritte Klasse, die eine assoziative Entität oder eine Verweistabelle zwischen den beiden Entitäten darstellt.
Die Referenztabelle muss Spalten für den Primärschlüssel jeder Entität in der in der Tabelle dargestellten Beziehung vom Typ „Mehrfach zueinander“ enthalten. In diesem Beispiel entspricht jede Zeile in der Verweistabelle einer Verknüpfung zwischen einer Playlist-Instanz und einer Song-Instanz, bei der der referenzierte Titel in der referenzierten Playlist enthalten ist.
Der nächste Schritt hängt davon ab, wie Sie diese verknüpften Entitäten abfragen möchten.
Wenn du Playlists und eine Liste der entsprechenden Songs für jede Playlist abfragen möchtest, erstelle eine neue Datenklasse, die ein einzelnes Playlist-Objekt und eine Liste aller Song-Objekte enthält, die in der Playlist enthalten sind.
Wenn du Songs und eine Liste der entsprechenden Playlists abfragen möchtest, erstelle eine neue Datenklasse mit einem einzelnen Song-Objekt und einer Liste aller Playlist-Objekte, in denen der Song enthalten ist.
In beiden Fällen modellieren Sie die Beziehung zwischen den Entitäten mithilfe der Property associateBy in der Annotation @Relation in jeder dieser Klassen, um die Verweis-Entität zu identifizieren, die die Beziehung zwischen der Playlist-Entität und der Song-Entität herstellt.
Fügen Sie der DAO-Klasse abschließend eine Methode hinzu, um die Abfragefunktion für Ihre App freizugeben.
getPlaylistsWithSongs: Mit dieser Methode wird die Datenbank abgefragt und alle resultierenden PlaylistWithSongs-Objekte zurückgegeben.
getSongsWithPlaylists: Mit dieser Methode wird die Datenbank abgefragt und alle resultierenden SongWithPlaylists-Objekte zurückgegeben.
Für diese Methoden muss Room jeweils zwei Abfragen ausführen. Fügen Sie daher beiden Methoden die Annotation @Transaction hinzu, damit die gesamte Operation atomar ausgeführt wird.
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();
Alle Inhalte und Codebeispiele auf dieser Seite unterliegen den Lizenzen wie im Abschnitt Inhaltslizenz beschrieben. Java und OpenJDK sind Marken oder eingetragene Marken von Oracle und/oder seinen Tochtergesellschaften.
Zuletzt aktualisiert: 2025-07-27 (UTC).
[[["Leicht verständlich","easyToUnderstand","thumb-up"],["Mein Problem wurde gelöst","solvedMyProblem","thumb-up"],["Sonstiges","otherUp","thumb-up"]],[["Benötigte Informationen nicht gefunden","missingTheInformationINeed","thumb-down"],["Zu umständlich/zu viele Schritte","tooComplicatedTooManySteps","thumb-down"],["Nicht mehr aktuell","outOfDate","thumb-down"],["Problem mit der Übersetzung","translationIssue","thumb-down"],["Problem mit Beispielen/Code","samplesCodeIssue","thumb-down"],["Sonstiges","otherDown","thumb-down"]],["Zuletzt aktualisiert: 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)."]]