Mengisi otomatis database Room Anda

Terkadang, Anda mungkin ingin memulai aplikasi Anda dengan database yang sudah terisi dengan sekumpulan data spesifik. Ini disebut mengisi otomatis database. Di Room 2.2.0 dan yang lebih tinggi, Anda dapat menggunakan metode API untuk mengisi otomatis database Room saat melakukan inisialisasi dengan konten dari file database dalam bentuk paket di sistem file perangkat.

Mengisi otomatis dari aset aplikasi

Untuk mengisi otomatis database Room dari file database dalam bentuk paket yang terletak di mana saja pada direktori assets/ aplikasi Anda, panggil metode createFromAsset() dari objek RoomDatabase.Builder Anda sebelum memanggil 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();

Metode createFromAsset() menerima argumen string yang berisi jalur relatif dari direktori assets/ ke file database dalam bentuk paket.

Mengisi otomatis dari sistem file

Untuk mengisi otomatis database Room dari file database dalam bentuk paket yang terletak di mana saja pada sistem file perangkat kecuali direktori assets/ aplikasi Anda, panggil metode createFromFile() dari objek RoomDatabase.Builder Anda sebelum memanggil 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();

Metode createFromFile() menerima argumen File untuk file database dalam bentuk paket. Room membuat salinan file yang ditetapkan, bukan membukanya secara langsung, jadi pastikan aplikasi Anda memiliki izin baca pada file tersebut.

Menangani migrasi yang menyertakan database dalam bentuk paket

File database dalam bentuk paket juga dapat mengubah cara database Room Anda menangani migrasi penggantian. Biasanya, saat migrasi destruktif diaktifkan dan Room harus melakukan migrasi tanpa jalur migrasi, Room akan menempatkan semua tabel dalam database dan membuat database kosong dengan skema yang ditentukan untuk versi target. Namun, jika Anda menyertakan file database dalam bentuk paket dengan jumlah yang sama seperti versi target, Room akan mencoba mengisi database yang baru dibuat ulang dengan konten file database dalam bentuk paket setelah melakukan migrasi destruktif.

Untuk informasi selengkapnya tentang migrasi database Room, lihat Memigrasikan database Room.

Bagian berikut menampilkan beberapa contoh cara kerja migrasi ini dalam praktiknya.

Contoh: Migrasi penggantian dengan database dalam bentuk paket

Ambil contoh:

  • Aplikasi Anda menentukan database Room di versi 3.
  • Instance database yang sudah diinstal pada perangkat berada di versi 2.
  • Ada file database dalam bentuk paket yang berada di versi 3.
  • Tidak ada jalur migrasi yang diimplementasikan dari versi 2 ke versi 3.
  • Migrasi destruktif diaktifkan.

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();

Berikut adalah hal yang akan terjadi dalam situasi ini:

  1. Karena database yang ditentukan dalam aplikasi Anda berada di versi 3 dan instance database yang sudah diinstal di perangkat berada di versi 2, migrasi diperlukan.
  2. Karena tidak ada rencana migrasi yang diimplementasikan dari versi 2 ke versi 3, migrasi yang diimplementasikan adalah migrasi fallback.
  3. Karena metode builder fallbackToDestructiveMigration()l dipanggil, migrasi fallback bersifat destruktif. Room akan menghapus instance database yang terinstal pada perangkat.
  4. Karena ada file database dalam bentuk paket yang berada di versi 3, Room akan membuat ulang database dan mengisinya menggunakan konten file database dalam bentuk paket. Selain itu, jika Anda memaketkan file database yang berada di versi 2, Room akan mencatat bahwa database tersebut tidak cocok dengan versi target dan tidak akan menggunakannya sebagai bagian dari migrasi penggantian.

Contoh: Migrasi yang diimplementasikan dengan database dalam bentuk paket

Anggaplah aplikasi Anda mengimplementasikan jalur migrasi dari versi 2 ke versi 3 sebagai gantinya:

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();

Berikut adalah hal yang akan terjadi dalam situasi ini:

  1. Karena database yang ditentukan di aplikasi Anda berada di versi 3 dan database yang sudah diinstal pada perangkat berada di versi 2, migrasi diperlukan.
  2. Karena terdapat jalur migrasi yang diimplementasikan dari versi 2 ke versi 3, Room akan menjalankan metode migrate() yang ditentukan untuk mengupdate instance database pada perangkat ke versi 3, yang mempertahankan data yang sudah ada dalam database. Room tidak menggunakan file database dalam bentuk paket karena Room hanya menggunakan file database tersebut jika terjadi migrasi fallback.

Contoh: Migrasi multi-langkah dengan database dalam bentuk paket

File database dalam bentuk paket juga dapat memengaruhi migrasi yang terdiri dari beberapa langkah. Pertimbangkan kasus berikut:

  • Aplikasi Anda menentukan database Room di versi 4.
  • Instance database yang sudah diinstal pada perangkat berada di versi 2.
  • Ada file database dalam bentuk paket yang berada di versi 3.
  • Ada jalur migrasi yang diimplementasikan dari versi 3 ke versi 4, tetapi bukan dari versi 2 ke versi 3.
  • Migrasi destruktif diaktifkan.

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();

Berikut adalah hal yang akan terjadi dalam situasi ini:

  1. Karena database yang ditentukan dalam aplikasi Anda berada di versi 4 dan instance database yang sudah diinstal di perangkat berada di versi 2, migrasi diperlukan.
  2. Karena tidak ada jalur migrasi yang diimplementasikan dari versi 2 ke versi 3, migrasi yang diimplementasikan adalah migrasi fallback.
  3. Karena metode builder fallbackToDestructiveMigration()l dipanggil, migrasi fallback bersifat destruktif. Room akan meletakkan instance database pada perangkat.
  4. Karena ada file database dalam bentuk paket yang berada di versi 3, Room akan membuat ulang database dan mengisinya menggunakan konten file database dalam bentuk paket.
  5. Database yang diinstal di perangkat kini berada di versi 3. Karena versi ini masih lebih rendah daripada versi yang ditentukan di aplikasi Anda, migrasi lain diperlukan.
  6. Karena ada jalur migrasi yang diimplementasikan dari versi 3 ke versi 4, Room akan menjalankan metode migrate() yang ditentukan untuk mengupdate instance database di perangkat ke versi 4, yang mempertahankan data yang disalin dari file database dalam bentuk paket versi 3.

Referensi lainnya

Untuk mempelajari lebih lanjut cara mengisi otomatis database Room, lihat referensi tambahan berikut.

Video

Blog