アプリを起動する際に、特定のデータセットをすでに読み込んでいるデータベースを使用したい場合があります。これを、データベースの事前取り込みといいます。Room 2.2.0 以降では、API メソッドを使用して、初期化時にデバイスのファイル システム内にある事前パッケージ化済みデータベース ファイルの内容を Room データベースに事前取り込みできます。
アプリアセットから事前取り込みする
事前パッケージ化済みデータベース ファイルから Room データベースに事前取り込みする際、データベース ファイルがアプリの assets/
ディレクトリ内にある場合は、次のように RoomDatabase.Builder
オブジェクトから createFromAsset()
メソッドを呼び出してから、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();
createFromAsset()
メソッドは、assets/
ディレクトリから事前パッケージ化済みデータベース ファイルへの相対パスが入った文字列引数を受け付けます。
ファイル システムから事前取り込みする
事前パッケージ化済みデータベース ファイルから Room データベースに事前取り込みする際、データベース ファイルがデバイスのファイル システムでアプリの assets/
ディレクトリの外にある場合は、RoomDatabase.Builder
オブジェクトから createFromFile()
メソッドを呼び出してから、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();
createFromFile()
メソッドは、事前パッケージ化済みデータベース ファイルの File
引数を受け付けます。Room で指定されたファイルが直接開かれるのではなく、コピーが作成されるため、アプリにファイルの読み取り権限があることを確認してください。
事前パッケージ化済みデータベースを含む移行の処理
事前パッケージ化済みデータベース ファイルによって、Room データベースでのフォールバック移行の処理方法も変わります。通常、破壊的移行が有効で、Room が移行パスなしで移行を実施する必要がある場合、Room はデータベース内のすべてのテーブルを削除し、ターゲット バージョンの指定されたスキーマで空のデータベースを作成します。ただし、ターゲット バージョンと同じ番号の事前パッケージ化済みデータベース ファイルを含めると、破壊的移行を実施した後に、事前パッケージ化済みデータベース ファイルの内容が新規に再作成されたデータベースに取り込まれます。
Room データベースの移行の詳細については、Room データベースを移行するをご覧ください。
以降のセクションでは、実際の動作の例を紹介します。
例: 事前パッケージ化済みデータベースを含むフォールバック移行
次の前提で説明します。
- バージョン 3 で Room データベースを定義している。
- デバイスにインストールされているデータベース インスタンスはバージョン 2 である。
- バージョン 3 の事前パッケージ化済みデータベース ファイルがある。
- バージョン 2 からバージョン 3 への移行パスは実装されていない。
- 破壊的移行が有効になっている。
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();
この場合は、次のようになります。
- アプリで定義されたデータベースがバージョン 3 で、デバイスにインストールされているデータベース インスタンスはバージョン 2 であるため、移行が必要です。
- バージョン 2 からバージョン 3 への移行プランが実装されていないため、この移行はフォールバック移行です。
fallbackToDestructiveMigration()
ビルダー メソッドが呼び出されるため、このフォールバック移行は破壊的です。デバイスにインストールされているデータベース インスタンスが削除されます。- バージョン 3 の事前パッケージ化済みデータベース ファイルがあるため、データベースが再作成され、事前パッケージ化済みデータベース ファイルの内容が取り込まれます。一方、事前パッケージ化済みデータベース ファイルがバージョン 2 の場合は、ターゲット バージョンと一致せず、フォールバック移行では使用されないことが通知されます。
例: 事前パッケージ化済みデータベースを含む実装済みの移行
次のように、バージョン 2 からバージョン 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();
この場合は、次のようになります。
- アプリで定義されたデータベースがバージョン 3 で、デバイスにインストールされているデータベースはバージョン 2 であるため、移行が必要です。
- バージョン 2 からバージョン 3 への移行パスが実装されているため、定義されている
migrate()
メソッドが実行され、すでにデータベースにあるデータを維持したまま、デバイス上のデータベース インスタンスがバージョン 3 に更新されます。フォールバック移行の場合にのみ事前パッケージ化済みデータベース ファイルが使用されるため、事前パッケージ化済みデータベース ファイルは使用されません。
例: 事前パッケージ化済みデータベースを含むマルチステップ移行
事前パッケージ化済みデータベース ファイルは、複数のステップで構成される移行にも影響します。次の場合を考えます。
- バージョン 4 で Room データベースを定義している。
- デバイスにインストールされているデータベース インスタンスはバージョン 2 である。
- バージョン 3 の事前パッケージ化済みデータベース ファイルがある。
- バージョン 3 からバージョン 4 への移行パスは実装されているが、バージョン 2 からバージョン 3 への移行パスは実装されていない。
- 破壊的移行が有効になっている。
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();
この場合は、次のようになります。
- アプリで定義されたデータベースがバージョン 4 で、デバイスにインストールされているデータベース インスタンスはバージョン 2 であるため、移行が必要です。
- バージョン 2 からバージョン 3 への移行パスが実装されていないため、この移行はフォールバック移行です。
fallbackToDestructiveMigration()
ビルダー メソッドが呼び出されるため、このフォールバック移行は破壊的です。デバイス上のデータベース インスタンスが削除されます。- バージョン 3 の事前パッケージ化済みデータベース ファイルがあるため、データベースが再作成され、事前パッケージ化済みデータベース ファイルの内容が取り込まれます。
- 現在、デバイスにインストールされているデータベースはバージョン 3 です。アプリで定義されているバージョンよりもまだ小さいため、移行がもう 1 回必要です。
- バージョン 3 からバージョン 4 への移行パスが実装されているため、定義されている
migrate()
メソッドが実行され、バージョン 3 の 事前パッケージ化済みデータベース ファイルから上書きコピーされたデータを維持したまま、デバイス上のデータベース インスタンスがバージョン 4 に更新されます。
参考情報
Room データベースの事前取り込みの詳細については、次の参考情報をご覧ください。
動画
- Room の新機能(Android Dev Summit '19)