Definire e eseguire query sulle relazioni one-to-one

Una relazione one-to-one tra due entità è una relazione in cui ogni istanza dell'entità principale corrisponde esattamente a un'istanza dell'entità secondaria e viceversa.

Ad esempio, considera un'app di streaming musicale in cui l'utente ha una raccolta di brani di sua proprietà. Ogni utente ha una sola raccolta e ogni raccolta corrisponde esattamente a un utente. Pertanto, esiste una relazione one-to-one tra l'entità User e l'entità Library.

Per definire ed eseguire query sulle relazioni one-to-one nel database:

  1. Definisci la relazione: crea classi per entrambe le entità e assicurati che una faccia riferimento alla chiave primaria dell'altra.
  2. Esegui query sulle entità: modella la relazione in una nuova classe di dati, e crea una funzione per recuperare i dati correlati.

Definisci la relazione

Per definire una relazione one-to-one, crea prima una classe per ciascuna delle due entità. Una delle entità deve includere una variabile che fa riferimento alla chiave primaria dell'altra entità.

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

@Entity
data class Library(
    @PrimaryKey val libraryId: Long,
    val userOwnerId: Long
)

Esegui query sulle entità

Per eseguire query sull'elenco degli utenti e delle raccolte corrispondenti, devi prima modellare la relazione one-to-one tra le due entità.

Per modellare la relazione, crea una nuova classe di dati in cui ogni istanza contiene un'istanza dell'entità principale e l'entità secondaria corrispondente. Aggiungi l' @Relation annotazione all'entità secondaria. Imposta parentColumns su il nome della colonna della chiave primaria dell'entità principale e imposta entityColumns sul nome della colonna dell'entità secondaria che fa riferimento alla chiave primaria dell'entità principale.

data class UserAndLibrary(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["userId"],
        entityColumns = ["userOwnerId"]
    )
    val library: Library
)

Infine, aggiungi una funzione alla classe Data Access Object (DAO) che restituisce tutte le istanze della classe di dati che associa l'entità principale all'entità secondaria. Aggiungi l'annotazione @Transaction per assicurarti che Room esegua l'intera operazione in modo atomico, perché questa funzione richiede a Room di eseguire due query.

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

Chiavi composite

Se definisci la relazione utilizzando chiavi composite, specifica più colonne in parentColumns e entityColumns. L'ordine delle colonne in parentColumns deve corrispondere all'ordine delle colonne in entityColumns.

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

@Entity
data class Library(
    @PrimaryKey val libraryId: Long,
    val userFirstName: String,
    val userLastName: String
)

data class UserAndLibrary(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["firstName", "lastName"],
        entityColumns = ["userFirstName", "userLastName"]
    )
    val library: Library
)