Cómo definir y consultar relaciones de uno a varios

Una relación de uno a varios entre dos entidades es una relación en la que cada instancia de la entidad principal corresponde a cero o más instancias de la entidad secundaria, pero cada instancia de la entidad secundaria solo puede corresponder una instancia de la entidad principal.

En el ejemplo de la app de transmisión de música, supongamos que el usuario puede organizar las canciones en playlists. Cada usuario puede crear tantas playlists como desee, pero un solo usuario crea cada playlist. Por lo tanto, existe una relación de uno a varios entre la entidad User y la entidad Playlist.

Sigue estos pasos para definir y consultar relaciones de uno a varios en tu base de datos:

  1. Define la relación: Crea clases para ambas entidades, con la entidad secundaria que hace referencia a la clave primaria de la entidad principal.
  2. Consulta las entidades: Modela la relación en una nueva clase de datos y, luego, implementa una función para recuperar los datos relacionados.

Define la relación

Para definir una relación de uno a varios, primero crea una clase para cada entidad. Al igual que en una relación de uno a uno, la entidad secundaria debe incluir una variable que haga referencia a la clave primaria de la entidad principal.

@Entity
data class User(
    @PrimaryKey val userId: Long,
    val name: String,
    val age: Int
)

@Entity
data class Playlist(
    @PrimaryKey val playlistId: Long,
    val userCreatorId: Long,
    val playlistName: String
)

Consulta las entidades

Para consultar la lista de usuarios y las playlists correspondientes, primero debes modelar la relación de uno a varios entre las dos entidades.

Para modelar la relación, crea una nueva clase de datos. Cada instancia de esta clase tiene una instancia de la entidad principal y una lista de todas las instancias de entidades secundarias correspondientes. Agrega la @Relation anotación a la propiedad que representa la lista de entidades secundarias. Establece parentColumns en el nombre de la columna de clave primaria de la entidad principal y establece entityColumns en el nombre de la columna de la entidad secundaria que hace referencia a la clave primaria de la entidad principal.

data class UserWithPlaylists(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["userId"],
        entityColumns = ["userCreatorId"]
    )
    val playlists: List<Playlist>
)

Por último, agrega una función a la clase de objeto de acceso a datos (DAO) que muestre todas las instancias de la clase de datos que vincula la entidad principal con la secundaria. Agrega la @Transaction anotación para que Room realice toda la operación de forma automática. Esta anotación es necesaria porque la función requiere que Room ejecute dos búsquedas.

@Transaction
@Query("SELECT * FROM User")
suspend fun getUsersWithPlaylists(): List<UserWithPlaylists>

Claves compuestas

Si defines la relación con claves compuestas, especifica varias columnas en parentColumns y entityColumns. El orden de las columnas en parentColumns debe coincidir con el orden de las columnas en entityColumns.

@Entity(primaryKeys = ["firstName", "lastName"])
data class User(
    val firstName: String,
    val lastName: String,
    val age: Int
)

@Entity
data class Playlist(
    @PrimaryKey val playlistId: Long,
    val userFirstName: String,
    val userLastName: String,
    val playlistName: String
)

data class UserWithPlaylists(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["firstName", "lastName"],
        entityColumns = ["userFirstName", "userLastName"]
    )
    val playlists: List<Playlist>
)