Definire e eseguire query sulle relazioni one-to-many

Una relazione uno a molti tra due entità è una relazione in cui ogni istanza dell'entità principale corrisponde a zero o più istanze dell'entità secondaria, ma ogni istanza dell'entità secondaria può corrispondere a una sola istanza dell'entità principale.

Nell'esempio dell'app di streaming musicale, supponiamo che l'utente abbia la possibilità di organizzare i suoi brani in playlist. Ogni utente può creare tutte le playlist che vuole, ma ogni playlist può essere creata da un solo utente. Pertanto, esiste una relazione one-to-many tra l'entità User e l'entità Playlist.

Per definire e eseguire query sulle relazioni uno a molti nel database:

  1. Definisci la relazione: crea classi per entrambe le entità, con l'entità secondaria che fa riferimento alla chiave primaria della principale.
  2. Esegui query sulle entità: modella la relazione in una nuova classe di dati e implementa un metodo per recuperare i dati correlati.

Definisci la relazione

Per definire una relazione uno a molti, crea innanzitutto una classe per le due entità. Come in una relazione uno a uno, l'entità figlio deve includere una variabile che rappresenta un riferimento alla chiave primaria dell'entità principale.

Kotlin

@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
)

Java

@Entity
public class User {
    @PrimaryKey public long userId;
    public String name;
    public int age;
}

@Entity
public class Playlist {
    @PrimaryKey public long playlistId;
    public long userCreatorId;
    public String playlistName;
}

Esegui una query sulle entità

Per eseguire query sull'elenco di utenti e sulle relative playlist, devi prima modellare la relazione tra le due entità

A tale scopo, crea una nuova classe di dati in cui ogni istanza contiene un'istanza dell'entità principale e un elenco di tutte le istanze dell'entità secondaria corrispondenti. Aggiungi l'annotazione @Relation all'istanza dell'entità secondaria, con parentColumn impostato sul nome della colonna della chiave primaria dell'entità principale e entityColumn impostato sul nome della colonna dell'entità secondaria che fa riferimento alla chiave primaria dell'entità principale.

Kotlin

data class UserWithPlaylists(
    @Embedded val user: User,
    @Relation(
          parentColumn = "userId",
          entityColumn = "userCreatorId"
    )
    val playlists: List<Playlist>
)

Java

public class UserWithPlaylists {
    @Embedded public User user;
    @Relation(
         parentColumn = "userId",
         entityColumn = "userCreatorId"
    )
    public List<Playlist> playlists;
}

Infine, aggiungi un metodo alla classe DAO che restituisca tutte le istanze della classe di dati che accoppiano l'entità principale e l'entità secondaria. Questo metodo richiede che Room esegua due query, quindi aggiungi l'annotazione @Transaction a questo metodo in modo che l'intera operazione venga eseguita in modo atomico.

Kotlin

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

Java

@Transaction
@Query("SELECT * FROM User")
public List<UserWithPlaylists> getUsersWithPlaylists();