Préremplir votre base de données Room

Vous pouvez parfois avoir besoin que votre application commence par une base de données déjà chargée avec un ensemble spécifique de données. C'est ce que l'on appelle le préremplissage d'une base de données. Dans la version 2.2.0 et les versions ultérieures, vous pouvez utiliser les méthodes d'API pour préremplir une base de données Room lors de l'initialisation avec le contenu d'un fichier de base de données préinstallé sur le système de fichiers de l'appareil.

Préremplir à partir d'un composant d'application

Pour préremplir une base de données Room à partir d'un fichier de base de données préinstallé situé n'importe où dans le répertoire assets/ de votre application, appelez la méthode createFromAsset() à partir de votre objet RoomDatabase.Builder avant d'appeler build() :

Kotlin

Room.databaseBuilder(appContext, AppDatabase::class.java, "Sample.db")
    .createFromAsset("database/myapp.db")
    .build()

Java

Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
    .createFromAsset("database/myapp.db")
    .build();

La méthode createFromAsset() accepte un argument de chaîne qui contient un chemin d'accès relatif du répertoire assets/ vers le fichier de base de données préinstallé.

Préremplir à partir du système de fichiers

Pour préremplir une base de données Room à partir d'un fichier de base de données préinstallé et situé n'importe où dans le système de fichiers de l'appareil, à l'exception du répertoire assets/ de votre application, appelez la méthode createFromFile(). de votre objet RoomDatabase.Builder avant d'appeler build() :

Kotlin

Room.databaseBuilder(appContext, AppDatabase::class.java, "Sample.db")
    .createFromFile(File("mypath"))
    .build()

Java

Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
    .createFromFile(new File("mypath"))
    .build();

La méthode createFromFile() accepte un argument File pour le fichier de base de données préinstallé. Room crée une copie du fichier désigné au lieu de l'ouvrir directement. Assurez-vous donc que votre application dispose des autorisations de lecture sur le fichier.

Gérer les migrations qui incluent des bases de données préinstallées

Les fichiers de base de données préinstallés peuvent également modifier la façon dont votre base de données Room gère les migrations de remplacement. En règle générale, lorsque les migrations destructives sont activées et que Room doit effectuer une migration sans chemin de migration, il supprime toutes les tables de la base de données et crée une base de données vide avec le schéma spécifié pour la version cible. Toutefois, si vous incluez un fichier de base de données préinstallé avec le même numéro que la version cible, Room tente de remplir le contenu de la nouvelle base de données avec le contenu de ce fichier après avoir effectué la migration destructive.

Pour en savoir plus sur la migration des bases de données Room, consultez la page Migrer des bases de données Room.

Les sections suivantes présentent quelques exemples concrets de fonctionnement.

Exemple : migration de remplacement avec une base de données préinstallée

Supposons que :

  • Votre application définit une base de données Room sur la version 3.
  • L'instance de base de données déjà installée sur l'appareil utilise la version 2.
  • Il existe un fichier de base de données préinstallé dans la version 3.
  • Aucun chemin de migration de la version 2 vers la version 3 n'a été implémenté.
  • Les migrations destructives sont activées.

Kotlin

// Database class definition declaring version 3.
@Database(version = 3)
abstract class AppDatabase : RoomDatabase() {
    ...
}

// Destructive migrations are enabled and a prepackaged database
// is provided.
Room.databaseBuilder(appContext, AppDatabase::class.java, "Sample.db")
    .createFromAsset("database/myapp.db")
    .fallbackToDestructiveMigration()
    .build()

Java

// Database class definition declaring version 3.
@Database(version = 3)
public abstract class AppDatabase extends RoomDatabase {
    ...
}

// Destructive migrations are enabled and a prepackaged database
// is provided.
Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
    .createFromAsset("database/myapp.db")
    .fallbackToDestructiveMigration()
    .build();

Voici le résultat :

  1. Étant donné que la base de données définie dans votre application est sur la version 3 et que l'instance de base de données déjà installée sur l'appareil est sur la version 2, une migration est nécessaire.
  2. Comme aucun plan de migration n'a été implémenté entre la version 2 et la version 3, il s'agit d'une migration de remplacement.
  3. Comme la méthode de compilation fallbackToDestructiveMigration() est appelée, la migration de remplacement est destructrice. Room supprime l'instance de base de données installée sur l'appareil.
  4. Étant donné qu'il existe un fichier de base de données préinstallé dans la version 3, Room recrée la base de données et l'insère à l'aide du contenu de ce fichier. Si, en revanche, vous utilisiez un fichier de base de données préinstallé dans la version 2, Room note qu'il ne correspond pas à la version cible et ne l'utilise donc pas dans le cadre de la migration de remplacement.

Exemple : implémentation d'une migration avec une base de données préinstallée

Supposons à la place que votre application implémente un chemin de migration de la version 2 vers la version 3 :

Kotlin

// Database class definition declaring version 3.
@Database(version = 3)
abstract class AppDatabase : RoomDatabase() {
    ...
}

// Migration path definition from version 2 to version 3.
val MIGRATION_2_3 = object : Migration(2, 3) {
    override fun migrate(database: SupportSQLiteDatabase) {
        ...
    }
}

// A prepackaged database is provided.
Room.databaseBuilder(appContext, AppDatabase::class.java, "Sample.db")
    .createFromAsset("database/myapp.db")
    .addMigrations(MIGRATION_2_3)
    .build()

Java

// Database class definition declaring version 3.
@Database(version = 3)
public abstract class AppDatabase extends RoomDatabase {
    ...
}

// Migration path definition from version 2 to version 3.
static final Migration MIGRATION_2_3 = new Migration(2, 3) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        ...
    }
};

// A prepackaged database is provided.
Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
    .createFromAsset("database/myapp.db")
    .addMigrations(MIGRATION_2_3)
    .build();

Voici le résultat :

  1. Étant donné que la base de données définie dans votre application est sur la version 3 et que la base de données déjà installée sur l'appareil est sur la version 2, une migration est nécessaire.
  2. Étant donné qu'un chemin de migration a été implémenté entre la version 2 et la version 3, Room exécute la méthode migrate() définie pour mettre à jour l'instance de base de données de l'appareil vers la version 3, ce qui préserve les données qui se trouvent déjà dans la base de données. Room n'utilise pas le fichier de base de données préinstallé, car il n'utilise ce type de fichiers que pour une migration de remplacement.

Exemple : migration en plusieurs étapes avec une base de données préinstallée

Les fichiers de base de données préinstallés peuvent également affecter les migrations constituées de plusieurs étapes. Prenons le cas suivant :

  • Votre application définit une base de données Room dans la version 4.
  • L'instance de base de données déjà installée sur l'appareil utilise la version 2.
  • Il existe un fichier de base de données préinstallé dans la version 3.
  • Un chemin de migration a été implémenté de la version 3 à la version 4, mais pas de la version 2 à la version 3.
  • Les migrations destructives sont activées.

Kotlin

// Database class definition declaring version 4.
@Database(version = 4)
abstract class AppDatabase : RoomDatabase() {
    ...
}

// Migration path definition from version 3 to version 4.
val MIGRATION_3_4 = object : Migration(3, 4) {
    override fun migrate(database: SupportSQLiteDatabase) {
        ...
    }
}

// Destructive migrations are enabled and a prepackaged database is
// provided.
Room.databaseBuilder(appContext, AppDatabase::class.java, "Sample.db")
    .createFromAsset("database/myapp.db")
    .addMigrations(MIGRATION_3_4)
    .fallbackToDestructiveMigration()
    .build()

Java

// Database class definition declaring version 4.
@Database(version = 4)
public abstract class AppDatabase extends RoomDatabase {
    ...
}

// Migration path definition from version 3 to version 4.
static final Migration MIGRATION_3_4 = new Migration(3, 4) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        ...
    }
};

// Destructive migrations are enabled and a prepackaged database is
// provided.
Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
    .createFromAsset("database/myapp.db")
    .addMigrations(MIGRATION_3_4)
    .fallbackToDestructiveMigration()
    .build();

Voici le résultat :

  1. Étant donné que la base de données définie dans votre application est sur la version 4 et que l'instance de base de données déjà installée sur l'appareil est sur la version 2, une migration est nécessaire.
  2. Comme aucun chemin de migration n'a été implémenté entre la version 2 et la version 3, il s'agit d'une migration de remplacement.
  3. Comme la méthode de compilation fallbackToDestructiveMigration() est appelée, la migration de remplacement est destructrice. Room supprime l'instance de base de données sur l'appareil.
  4. Étant donné qu'il existe un fichier de base de données préinstallé dans la version 3, Room recrée la base de données et l'insère à l'aide du contenu de ce fichier.
  5. La base de données installée sur l'appareil utilise désormais la version 3. Comme elle est encore inférieure à la version définie dans votre application, une autre migration est nécessaire.
  6. Étant donné qu'un chemin de migration a été implémenté entre la version 3 et la version 4, Room exécute la méthode migrate() définie pour mettre à jour l'instance de base de données de l'appareil vers la version 4, ce qui préserve les données qui ont été copiées à partir du fichier de base de données préinstallé de la version 3.

Ressources supplémentaires

Pour en savoir plus sur le préremplissage d'une base de données Room, consultez les ressources supplémentaires suivantes.

Vidéos

Blogs