Définir des données à l'aide d'entités Room

Lorsque vous utilisez la bibliothèque de persistance Room pour stocker les données de votre application, vous définissez des entités représentant les objets que vous souhaitez stocker. Chaque entité correspond à une table de la base de données Room associée et chaque instance d'une entité représente une ligne de données de la table correspondante.

L'utilisation d'entités Room vous permet de définir votre schéma de base de données sans avoir à écrire de code SQL.

Anatomie d'une entité

Vous définissez chaque entité Room en tant que classe annotée avec @Entity. Une entité Room comprend des propriétés pour chaque colonne de la table correspondante dans la base de données, y compris une ou plusieurs colonnes qui constituent la clé primaire.

Le code suivant est un exemple d'entité qui définit une table User avec des colonnes pour l'ID, le prénom et le nom :

@Entity
data class User(
    @PrimaryKey val id: Int,
    val firstName: String,
    val lastName: String
)

Par défaut, Room utilise le nom de la classe comme nom de la table de base de données. Si vous souhaitez que la table porte un autre nom, définissez la tableName propriété de l' @Entity annotation. De même, Room utilise par défaut les noms de propriétés comme noms de colonnes dans la base de données. Si vous souhaitez qu'une colonne porte un autre nom, ajoutez l' @ColumnInfo annotation à la propriété et définissez la name propriété. L'exemple suivant montre des noms personnalisés pour une table et ses colonnes :

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "first_name") val firstName: String,
    @ColumnInfo(name = "last_name") val lastName: String
)

Définir une clé primaire

Vous devez définir une clé primaire pour chaque entité Room afin d' identifier de manière unique chaque ligne dans la table de base de données correspondante. Pour ce faire, annotez une seule colonne avec @PrimaryKey :

@PrimaryKey val id: Int

Définir une clé primaire composite

Si les instances d'une entité doivent être identifiées de manière unique par une combinaison de plusieurs colonnes, vous pouvez définir une clé primaire composite en répertoriant ces colonnes dans la primaryKeys propriété de @Entity :

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

Ignorer des propriétés

Par défaut, Room crée une colonne pour chaque propriété définie dans l'entité. Pour empêcher Room de conserver une propriété, annotez-la avec @Ignore :

@Entity
data class User(
    @PrimaryKey val id: Int,
    val firstName: String,
    val lastName: String,
    @Ignore val picture: Bitmap? = null
)

Si une entité hérite des propriétés d'une entité parente, utilisez la ignoredColumns propriété de l'@Entity annotation :

open class User {
    var picture: Bitmap? = null
}

@Entity(ignoredColumns = ["picture"])
data class RemoteUser(
    @PrimaryKey val id: Int,
    val hasVpn: Boolean
) : User()

Room est compatible avec plusieurs annotations qui vous permettent de rechercher des informations dans vos tables de base de données.

Prise en charge de la recherche en texte intégral

Si votre application nécessite une recherche en texte intégral (FTS) rapide, sauvegardez vos entités avec une table virtuelle. Utilisez l'extension SQLite FTS3 ou FTS4 ou l' extension SQLite FTS5.

Pour utiliser cette fonctionnalité, ajoutez l'@Fts3, @Fts4 ou @Fts5 annotation à une entité.

// Use `@Fts3` only if your app has strict disk space requirements.
@Fts4
@Entity(tableName = "users")
data class User(
    // Specifying a primary key for an FTS-table-backed entity is optional,
    // but if you include one, it must an INTEGER type and column name "rowid".
    @PrimaryKey @ColumnInfo(name = "rowid") val id: Long,
    @ColumnInfo(name = "first_name") val firstName: String
)

Pour personnaliser la façon dont les informations de la base de données sont tokenisées dans les tables FTS, utilisez l'option tokenizer. Room fournit plusieurs tokeniseurs intégrés via FtsOptions, y compris TOKENIZER_SIMPLE, TOKENIZER_PORTER et TOKENIZER_UNICODE61 :

@Fts4(tokenizer = FtsOptions.TOKENIZER_UNICODE61)
@Entity(tableName = "users")
data class User(
    @PrimaryKey @ColumnInfo(name = "rowid") val id: Long,
    @ColumnInfo(name = "first_name") val firstName: String
)

Room offre plusieurs autres options pour définir des entités reposant sur FTS, y compris l'ordre des résultats, la suppression d'index de colonnes et les tables gérées en tant que contenu externe. Pour en savoir plus sur ces options, consultez la FtsOptions référence.

Indexer des colonnes spécifiques

Si vous utilisez AndroidSQLiteDriver et que vous devez prendre en charge les versions du SDK qui ne sont pas compatibles avec les entités reposant sur une table FTS3, FTS4 ou FTS5, vous pouvez toujours indexer certaines colonnes de la base de données pour accélérer vos requêtes. Si vous utilisez BundledSQLiteDriver, Room est compatible avec toutes les versions de FTS , quelle que soit la version du SDK Android.

Pour ajouter des index à une entité, ajoutez la indices propriété dans l' @Entity annotation. Répertoriez les noms de colonnes à inclure dans l'index ou l'index composite. L'extrait de code suivant montre comment ajouter des index :

@Entity(indices = [Index(value = ["last_name", "address"])])
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "first_name") val firstName: String,
    @ColumnInfo(name = "last_name") val lastName: String,
    val address: String?,
)

Parfois, certaines colonnes ou groupes de colonnes d'une base de données doivent contenir des valeurs uniques. Pour appliquer cette unicité, définissez la unique propriété d' une @Index annotation sur true. L'exemple de code suivant montre comment appliquer cette unicité :

@Entity(indices = [Index(value = ["first_name", "last_name"], unique = true)])
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "first_name") val firstName: String,
    @ColumnInfo(name = "last_name") val lastName: String,
)