Wenn Ihre App mit einer Datenbank gestartet werden soll, in die bereits bestimmte Daten geladen wurden, können Sie die Datenbank vorab mit Daten füllen. In Room können Sie APIs verwenden, um eine Datenbank bei der Initialisierung mit Inhalten aus einer vorverpackten Datenbankdatei im Dateisystem des Geräts zu füllen.
Vorabfüllen aus einem App-Asset
Wenn Sie eine Room-Datenbank aus einer vorverpackten Datenbankdatei füllen möchten, die sich
an einer beliebigen Stelle im Verzeichnis assets/ Ihrer App befindet, rufen Sie die Funktion createFromAsset
aus Ihrem RoomDatabase.Builder Objekt auf, bevor Sie build aufrufen:
Room.databaseBuilder<AppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .build()
Die Funktion createFromAsset akzeptiert ein String-Argument, das einen relativen Pfad vom Verzeichnis assets/ zur vorverpackten Datenbankdatei enthält.
Vorabfüllen aus dem Dateisystem
Wenn Sie eine Room-Datenbank aus einer vorverpackten Datenbankdatei füllen möchten, die sich
an einer beliebigen Stelle im Dateisystem des Geräts außer im Verzeichnis assets/ Ihrer App befindet,
rufen Sie die Funktion createFromFile aus Ihrem RoomDatabase.Builder
Objekt auf, bevor Sie build aufrufen:
Room.databaseBuilder<AppDatabase>(appContext, "sample.db") .createFromFile(File("mypath")) .build()
Die createFromFile Funktion akzeptiert ein File Argument für die
vorverpackte Datenbankdatei. Room erstellt eine Kopie der angegebenen Datei, anstatt sie direkt zu öffnen. Achten Sie daher darauf, dass Ihre App Leseberechtigungen für die Datei hat.
Migrationen mit vorverpackten Datenbanken verarbeiten
Vorverpackte Datenbankdateien können auch die Art und Weise ändern, wie Ihre Room-Datenbank Fallback-Migrationen verarbeitet. Wenn destruktive Migrationen aktiviert sind und Room eine Migration ohne Migrationspfad durchführen muss, löscht Room normalerweise alle Tabellen in der Datenbank und erstellt eine leere Datenbank mit dem angegebenen Schema für die Zielversion. Wenn Sie jedoch eine vorverpackte Datenbankdatei mit derselben Nummer wie die Zielversion einfügen, füllt Room die neu erstellte Datenbank nach der destruktiven Migration mit den Inhalten der vorverpackten Datenbankdatei.
Weitere Informationen zu Room-Datenbankmigrationen finden Sie unter Room-Datenbank migrieren.
In den folgenden Abschnitten werden einige Beispiele für die praktische Anwendung beschrieben.
Beispiel: Fallback-Migration mit einer vorverpackten Datenbank
Angenommen:
- Ihre App definiert eine Room-Datenbank in Version 3.
- Die bereits auf dem Gerät installierte Datenbankinstanz hat Version 2.
- Es gibt eine vorverpackte Datenbankdatei in Version 3.
- Es ist kein Migrationspfad von Version 2 zu Version 3 implementiert.
- Destruktive Migrationen sind aktiviert.
// Database class definition declaring version 3. @Database(entities = [SampleEntity::class], version = 3) abstract class FallbackAppDatabase : RoomDatabase() { // ... } fun createFallbackDb(appContext: Context) { Room.databaseBuilder<FallbackAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .fallbackToDestructiveMigration() .build() }
In dieser Situation passiert Folgendes:
- Da die in Ihrer App definierte Datenbank Version 3 hat und die bereits auf dem Gerät installierte Datenbankinstanz Version 2 hat, ist eine Migration erforderlich.
- Da es keinen implementierten Migrationsplan von Version 2 zu Version 3 gibt, ist die Migration eine Fallback-Migration.
- Da Sie die
fallbackToDestructiveMigrationBuilder Funktion aufrufen, ist die Fallback-Migration destruktiv. Room löscht die auf dem Gerät installierte Datenbankinstanz. - Da es eine vorverpackte Datenbankdatei in Version 3 gibt, erstellt Room die Datenbank neu und füllt sie mit den Inhalten der vorverpackten Datenbankdatei. Wenn Ihre vorverpackte Datenbankdatei Version 2 hat, stellt Room fest, dass sie nicht mit der Zielversion übereinstimmt, und verwendet sie nicht für die Fallback-Migration.
Beispiel: Implementierte Migration mit einer vorverpackten Datenbank
Angenommen, Ihre App implementiert einen Migrationspfad von Version 2 zu Version 3:
// Database class definition declaring version 3. @Database(entities = [SampleEntity::class], version = 3) abstract class ImplementedAppDatabase : RoomDatabase() { // ... } // Migration path definition from version 2 to version 3. val MIGRATION_2_3 = object : Migration(2, 3) { override suspend fun migrate(connection: SQLiteConnection) { // ... } } fun createImplementedDb(appContext: Context) { Room.databaseBuilder<ImplementedAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .addMigrations(MIGRATION_2_3) .build() }
In dieser Situation passiert Folgendes:
- Da die in Ihrer App definierte Datenbank Version 3 hat und die bereits auf dem Gerät installierte Datenbank Version 2 hat, ist eine Migration erforderlich.
- Da es einen implementierten Migrationspfad von Version 2 zu Version 3 gibt,
führt Room die definierte Funktion
migrateaus, um die Datenbankinstanz auf dem Gerät auf Version 3 zu aktualisieren. Die bereits in der Datenbank vorhandenen Daten bleiben dabei erhalten. Room verwendet die vorverpackte Datenbankdatei nicht, da vorverpackte Datenbankdateien nur im Fall einer Fallback-Migration verwendet werden.
Beispiel: Mehrstufige Migration mit einer vorverpackten Datenbank
Vorverpackte Datenbankdateien können sich auch auf Migrationen aus mehreren Schritten auswirken. Betrachten Sie den folgenden Fall:
- Ihre App definiert eine Room-Datenbank in Version 4.
- Die bereits auf dem Gerät installierte Datenbankinstanz hat Version 2.
- Es gibt eine vorverpackte Datenbankdatei in Version 3.
- Es ist ein Migrationspfad von Version 3 zu Version 4 implementiert, aber nicht von Version 2 zu Version 3.
- Destruktive Migrationen sind aktiviert.
// Database class definition declaring version 4. @Database(entities = [SampleEntity::class], version = 4) abstract class MultiStepAppDatabase : RoomDatabase() { // ... } val MIGRATION_3_4 = object : Migration(3, 4) { override suspend fun migrate(connection: SQLiteConnection) { // ... } } fun createMultiStepDb(appContext: Context) { Room.databaseBuilder<MultiStepAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .addMigrations(MIGRATION_3_4) .fallbackToDestructiveMigration() .build() }
In dieser Situation passiert Folgendes:
- Da die in Ihrer App definierte Datenbank Version 4 hat und die bereits auf dem Gerät installierte Datenbankinstanz Version 2 hat, ist eine Migration erforderlich.
- Da es keinen implementierten Migrationspfad von Version 2 zu Version 3 gibt, ist die Migration eine Fallback-Migration.
- Da Sie die
fallbackToDestructiveMigrationBuilder Funktion aufrufen, ist die Fallback-Migration destruktiv. Room löscht die Datenbankinstanz auf dem Gerät. - Da es eine vorverpackte Datenbankdatei in Version 3 gibt, erstellt Room die Datenbank neu und füllt sie mit den Inhalten der vorverpackten Datenbankdatei.
- Die auf dem Gerät installierte Datenbank hat jetzt Version 3. Da sie immer noch niedriger ist als die in Ihrer App definierte Version, ist eine weitere Migration erforderlich.
- Da es einen implementierten Migrationspfad von Version 3 zu Version 4 gibt,
führt Room die definierte Funktion
migrateaus, um die Datenbankinstanz auf dem Gerät auf Version 4 zu aktualisieren. Die Daten, die aus der vorverpackten Datenbankdatei der Version 3 kopiert wurden, bleiben dabei erhalten.