Room veritabanınızı önceden doldurma

Bazen uygulamanızın belirli bir veri kümesi halihazırda yüklü olan bir veritabanıyla başlamasını isteyebilirsiniz. Bu işleme, veritabanını önceden doldurma denir. Oda 2.2.0 ve sonraki sürümlerde, başlatma sırasında Oda veritabanını cihazın dosya sistemindeki önceden paketlenmiş bir veritabanı dosyasının içeriğiyle önceden doldurmak için API yöntemlerini kullanabilirsiniz.

Uygulama öğesinden önceden doldurma

Uygulamanızın assets/ dizininin herhangi bir yerinde bulunan önceden paketlenmiş bir veritabanı dosyasından bir Oda veritabanını önceden doldurmak için build() çağırmadan önce RoomDatabase.Builder nesnenizden createFromAsset() yöntemini çağırın:

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() yöntemi, assets/ dizininden önceden paketlenmiş veritabanı dosyasına giden göreli bir yol içeren dize bağımsız değişkenlerini kabul eder.

Dosya sisteminden önceden doldurma

Bir Oda veritabanını, uygulamanızın assets/ dizini dışında, cihazın dosya sisteminde herhangi bir yerde bulunan önceden paketlenmiş bir veritabanı dosyasından önceden doldurmak için build() başlatmadan önce RoomDatabase.Builder nesnenizden createFromFile() yöntemini çağırın:

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() yöntemi, önceden paketlenmiş veritabanı dosyası için File bağımsız değişkenini kabul eder. Oda, belirtilen dosyanın doğrudan açmak yerine bir kopyasını oluşturur. Bu nedenle, uygulamanızın dosyada okuma izinlerine sahip olduğundan emin olun.

Önceden paketlenmiş veritabanlarını içeren taşıma işlemlerini yönetme

Önceden paketlenmiş veritabanı dosyaları, Room veritabanınızın yedek taşımaları işleme şeklini de değiştirebilir. Normalde, yıkıcı taşıma işlemleri etkinleştirildiğinde ve Odanın taşıma yolu olmadan bir taşıma işlemi gerçekleştirmesi gerektiğinde Oda, veritabanındaki tüm tabloları bırakır ve hedef sürüm için belirtilen şemayla boş bir veritabanı oluşturur. Ancak hedef sürümle aynı sayıya sahip önceden paketlenmiş bir veritabanı dosyası eklerseniz Oda, yıkıcı taşıma işleminden sonra yeni oluşturulan veritabanını önceden paketlenmiş veritabanı dosyasının içeriğiyle doldurmaya çalışır.

Oda veritabanı taşıma işlemleri hakkında daha fazla bilgi için Oda veritabanını taşıma başlıklı makaleye bakın.

Aşağıdaki bölümlerde, bunun pratikte nasıl işlediğine dair birkaç örnek sunulmaktadır.

Örnek: Önceden paketlenmiş veritabanıyla yedek taşıma

Aşağıdakini varsayalım:

  • Uygulamanız sürüm 3'te bir Oda veritabanı tanımlıyor.
  • Cihazda yüklü olan veritabanı örneği sürüm 2'dedir.
  • Sürüm 3'te olan önceden paketlenmiş bir veritabanı dosyası var.
  • Sürüm 2'den sürüm 3'e kadar uygulanan bir taşıma yolu yoktur.
  • Yıkıcı taşıma işlemleri etkindir.

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

Bu durumda şunlar olur:

  1. Uygulamanızda tanımlanan veritabanı sürüm 3'te ve cihazda zaten yüklü olan veritabanı örneği sürüm 2'de olduğundan taşıma işlemi gereklidir.
  2. 2. sürüm ile 3. sürüm arasında herhangi bir taşıma planı bulunmadığından taşıma işlemi yedek bir taşımadır.
  3. fallbackToDestructiveMigration() oluşturucu yöntemi adlandırıldığı için yedek taşıma işlemi kalıcıdır. Oda, cihazda yüklü olan veritabanı örneğini bırakır.
  4. Sürüm 3'te önceden paketlenmiş bir veritabanı dosyası bulunduğu için Room, veritabanını yeniden oluşturur ve önceden paketlenmiş veritabanı dosyasının içeriklerini kullanarak doldurur. Öte yandan, önceden paketlenmiş veritabanı dosyanızın sürüm 2'de olması durumunda Room, hedef sürümle eşleşmediğini ve bu dosyayı yedek taşımanın bir parçası olarak kullanmayacağını not eder.

Örnek: Önceden paketlenmiş veritabanıyla uygulanan taşıma

Bunun yerine, uygulamanızın sürüm 2'den sürüm 3'e bir taşıma yolu uyguladığını varsayalım:

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

Bu durumda şunlar olur:

  1. Uygulamanızda tanımlanan veritabanı sürüm 3'te ve cihazda halihazırda yüklü olan veritabanı sürüm 2'de olduğundan taşıma işlemi gereklidir.
  2. Sürüm 2'den sürüm 3'e uygulanmış bir taşıma yolu bulunduğundan oda, cihazdaki veritabanı örneğini sürüm 3'e güncellemek için tanımlı migrate() yöntemini çalıştırır ve böylece veritabanında zaten bulunan verileri korur. Room, önceden paketlenmiş veritabanı dosyalarını yalnızca yedek taşıma durumunda kullandığından oda önceden paketlenmiş veritabanı dosyasını kullanmıyor.

Örnek: Önceden paketlenmiş veritabanıyla çok adımlı taşıma

Önceden paketlenmiş veritabanı dosyaları da birden çok adımdan oluşan taşıma işlemlerini etkileyebilir. Aşağıdaki durumu göz önünde bulundurun:

  • Uygulamanız sürüm 4'te bir Oda veritabanı tanımlıyor.
  • Cihazda yüklü olan veritabanı örneği sürüm 2'dedir.
  • Sürüm 3'te olan önceden paketlenmiş bir veritabanı dosyası var.
  • Sürüm 3 ile sürüm 4 arasında uygulanmış bir taşıma yolu vardır ancak sürüm 2 ile sürüm 3 arasında bir geçiş yoktur.
  • Yıkıcı taşıma işlemleri etkindir.

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

Bu durumda şunlar olur:

  1. Uygulamanızda tanımlanan veritabanı sürüm 4'te ve cihazda zaten yüklü olan veritabanı örneği sürüm 2'de olduğundan taşıma işlemi gereklidir.
  2. Sürüm 2 ile sürüm 3 arasında uygulanmış bir taşıma yolu bulunmadığından taşıma işlemi yedek bir taşımadır.
  3. fallbackToDestructiveMigration() oluşturucu yöntemi adlandırıldığı için yedek taşıma işlemi kalıcıdır. Oda, cihazdaki veritabanı örneğini bırakır.
  4. Sürüm 3'te önceden paketlenmiş bir veritabanı dosyası bulunduğu için Room, veritabanını yeniden oluşturur ve önceden paketlenmiş veritabanı dosyasının içeriklerini kullanarak doldurur.
  5. Cihaza yüklenen veritabanı artık sürüm 3'tedir. Bu, uygulamanızda tanımlanan sürümden hâlâ düşük olduğu için başka bir taşıma işlemi gerekir.
  6. Sürüm 3'ten sürüm 4'e uygulanmış bir taşıma yolu bulunduğundan oda, cihazdaki veritabanı örneğini sürüm 4'e güncellemek için tanımlı migrate() yöntemini çalıştırır ve böylece sürüm 3'teki önceden paketlenmiş veritabanı dosyasından kopyalanan verileri korur.

Ek kaynaklar

Bir Oda veritabanını önceden doldurma hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynakları inceleyin.

Videolar

Bloglar