Oda kalıcılık kitaplığı, SQLite üzerinde bir soyutlama katmanı sağlar. Böylece, daha güçlü veritabanı erişimi sağlar ve SQLite'ın tüm gücünden yararlanır. Bu sayfa, Kotlin Multiplatform (KMP) projelerinde Room'un kullanılmasına odaklanmaktadır. Oda kullanımı hakkında daha fazla bilgi için Oda'yı kullanarak verileri yerel bir veritabanına kaydetme bölümüne veya resmi örneklerimize bakın.
Bağımlılıkları ayarlama
Oda'nın KMP'yi destekleyen mevcut sürümü 2.7.0-alpha01 veya sonraki bir sürümdür.
KMP projenizde Room'u kurmak için modülünüzün build.gradle.kts
dosyasına yapıların bağımlılıklarını ekleyin:
androidx.room:room-gradle-plugin
- Oda şemalarını yapılandırmak için Gradle Eklentisiandroidx.room:room-compiler
- Kod oluşturan KSP işlemcisiandroidx.room:room-runtime
- Kitaplığın çalışma zamanı kısmıandroidx.sqlite:sqlite-bundled
- (İsteğe bağlı) Paket haline getirilen SQLite kitaplığı
Buna ek olarak, odanın SQLite sürücüsünü yapılandırmanız gerekir. Bu sürücüler, hedef platforma göre farklılık gösterir. Mevcut sürücü uygulamalarının açıklamaları için Sürücü uygulamaları bölümüne bakın.
Ek kurulum bilgileri için aşağıdakilere bakın:
- Room Gradle Plugin kullanarak şema konumunu ayarlayın.
- KSP (Kotlin Multiplatform ile).
- Çalışma zamanı bağımlılıkları ekleme.
Veritabanı sınıflarını tanımlama
Paylaşılan KMP modülünüzün ortak kaynak kümesindeki DAO'lar ve varlıklarla birlikte @Database
ek açıklamasına sahip bir veritabanı sınıfı oluşturmanız gerekir. Bu sınıfların ortak kaynaklara yerleştirilmesi, tüm hedef platformlarda paylaşılmasına olanak tanır.
// shared/src/commonMain/kotlin/Database.kt
@Database(entities = [TodoEntity::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun getDao(): TodoDao
}
@Dao
interface TodoDao {
@Insert
suspend fun insert(item: TodoEntity)
@Query("SELECT count(*) FROM TodoEntity")
suspend fun count(): Int
@Query("SELECT * FROM TodoEntity")
fun getAllAsFlow(): Flow<List<TodoEntity>>
}
@Entity
data class TodoEntity(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
val title: String,
val content: String
)
Platforma özel Oda uygulamaları oluşturmak için gerçek / beklenen bildirimleri kullanabileceğinizi unutmayın. Örneğin, expect
kullanarak ortak kodda tanımlanmış platforma özgü bir DAO ekleyebilir ve ardından actual
tanımlarını platforma özel kaynak kümelerindeki ek sorgularla belirtebilirsiniz.
Veritabanı oluşturucuyu oluşturma
Her platformda Room örneğini oluşturmak için bir veritabanı oluşturucu tanımlamanız gerekir. Bu, dosya sistemi API'lerindeki farklılıklar nedeniyle platforma özel kaynak kümelerinde bulunması gereken API'nin tek parçasıdır. Örneğin, Android'de veritabanı konumu genellikle Context.getDatabasePath()
API aracılığıyla, iOS'te ise veritabanı konumu NSHomeDirectory
kullanılarak alınır.
Android
Veritabanı örneğini oluşturmak için veritabanı yoluyla birlikte bir Context belirtin. Veritabanı fabrikası belirtmeniz gerekmez.
// shared/src/androidMain/kotlin/Database.kt
fun getDatabaseBuilder(ctx: Context): RoomDatabase.Builder<AppDatabase> {
val appContext = ctx.applicationContext
val dbFile = appContext.getDatabasePath("my_room.db")
return Room.databaseBuilder<AppDatabase>(
context = appContext,
name = dbFile.absolutePath
)
}
iOS
Veritabanı örneği oluşturmak için veritabanı yoluyla birlikte bir veritabanı fabrikası sağlayın. Veritabanı fabrikası, adı KClass<T>
türünde bir alıcıyla instantiateImpl
olan oluşturulmuş bir uzantı işlevini çağıran bir lambda işlevidir. Burada T
, @Database
ek açıklamalı sınıfının türüdür.
// shared/src/iosMain/kotlin/Database.kt
fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
val dbFilePath = NSHomeDirectory() + "/my_room.db"
return Room.databaseBuilder<AppDatabase>(
name = dbFilePath,
factory = { AppDatabase::class.instantiateImpl() }
)
}
JVM (Masaüstü)
Veritabanı örneğini oluşturmak için yalnızca veritabanı yolunu belirtin. Veritabanı fabrikası sağlamanız gerekmez.
// shared/src/commonMain/kotlin/Database.kt
fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
val dbFile = File(System.getProperty("java.io.tmpdir"), "my_room.db")
return Room.databaseBuilder<AppDatabase>(
name = dbFile.absolutePath,
)
}
Veritabanı örneği oluşturma
Platforma özel kurucuların birinden RoomDatabase.Builder
edindikten sonra Room veritabanının geri kalanını gerçek veritabanı örneklendirmesiyle birlikte ortak kodda yapılandırabilirsiniz.
// shared/src/commonMain/kotlin/Database.kt
fun getRoomDatabase(
builder: RoomDatabase.Builder<AppDatabase>
): AppDatabase {
return builder
.addMigrations(MIGRATIONS)
.fallbackToDestructiveMigrationOnDowngrade()
.setDriver(BundledSQLiteDriver())
.setQueryCoroutineContext(Dispatchers.IO)
.build()
}
SQLiteDriver seçme
Önceki kod snippet'lerinde BundledSQLiteDriver
kullanılmıştır. Bu, kaynaktan derlenen SQLite'ı içeren ve tüm platformlarda en tutarlı ve güncel SQLite sürümünü sunan, önerilen sürücüdür. OS tarafından sağlanan SQLite'ı kullanmak isterseniz platforma özgü bir sürücü belirten platforma özgü kaynak kümelerinde setDriver
API'yi kullanın. Android'de AndroidSQLiteDriver
, iOS'te ise NativeSQLiteDriver
kullanılabilir. NativeSQLiteDriver
özelliğini kullanmak için iOS uygulamasının sistem SQLite'sine dinamik olarak bağlanmasını sağlayacak bir bağlayıcı seçeneği sağlamanız gerekir.
// shared/build.gradle.kts
kotlin {
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "TodoApp"
isStatic = true
// Required when using NativeSQLiteDriver
linkerOpts.add("-lsqlite3")
}
}
}
Farklılıklar
Room, başlangıçta Android kitaplığı olarak geliştirildi ve daha sonra API uyumluluğuna odaklanarak KMP'ye taşındı. Room'un KMP sürümü, platformlar arasında ve Android'e özgü sürümden biraz farklıdır. Bu farklılıklar aşağıda listelenmiştir ve açıklanmıştır.
DAO işlevlerini engelleme
KMP için Room kullanılırken Android dışı platformlar için derlenen tüm DAO işlevlerinin, Flow
gibi reaktif dönüş türleri hariç suspend
işlevi olması gerekir.
// shared/src/commonMain/kotlin/MultiplatformDao.kt
@Dao
interface MultiplatformDao {
// ERROR: Blocking function not valid for non-Android targets
@Query("SELECT * FROM Entity")
fun blockingQuery(): List<Entity>
// OK
@Query("SELECT * FROM Entity")
suspend fun query(): List<Entity>
// OK
@Query("SELECT * FROM Entity")
fun queryFlow(): Flow<List<Entity>>
// ERROR: Blocking function not valid for non-Android targets
@Transaction
fun blockingTransaction() { // … }
// OK
@Transaction
suspend fun transaction() { // … }
}
Oda, Kotlin'in birden fazla platformda zengin özelliklere sahip eşzamansız kotlinx.coroutines
kitaplığından yararlanabiliyor. suspend
işlevleri, mevcut kod tabanıyla geriye dönük uyumluluğu korumak amacıyla Android'e özel DAO'lar haricinde, bir KMP projesinde derlenen DAO'lar için en uygun işlevi sağlamak amacıyla zorunlu kılınır.
KMP ile özellik farklılıkları
Bu bölümde, oda özelliklerinin KMP ve Android platformu sürümleri arasında nasıl farklılık gösterdiği açıklanmaktadır.
@RawQuery DAO işlevleri
Android dışı platformlar için derlenen ve @RawQuery
ek açıklamasına sahip olan işlevler hata verir. Room'un gelecekteki bir sürümünde @RawQuery
desteği eklemeyi planlıyoruz.
Sorgu Geri Çağırması
Sorgu geri çağırmalarını yapılandırmaya yönelik aşağıdaki API'ler ortak olarak mevcut olmadığından Android dışındaki platformlarda kullanılamaz.
RoomDatabase.Builder.setQueryCallback
RoomDatabase.QueryCallback
Odanın gelecekteki bir sürümünde sorgu geri çağırma desteği eklemeyi planlıyoruz.
RoomDatabase.QueryCallback
geri çağırma arayüzüyle birlikte sorgu geri çağırma (RoomDatabase.Builder.setQueryCallback
) içeren bir RoomDatabase
yapılandıran API yaygın olarak kullanılmadığı için Android dışındaki diğer platformlarda kullanılamaz.
Veritabanını Otomatik Kapatma
Zaman aşımından (RoomDatabase.Builder.setAutoCloseTimeout
) sonra otomatik kapanmayı etkinleştiren API yalnızca Android'de kullanılabilir ve diğer platformlarda kullanılamaz.
Paket Hazır Veritabanı
Mevcut bir veritabanı (yani, önceden paketlenmiş bir veritabanı) kullanarak RoomDatabase
oluşturmak için aşağıdaki API'ler ortak olarak mevcut olmadığından Android dışındaki diğer platformlarda kullanılamaz. Bu API'ler şunlardır:
RoomDatabase.Builder.createFromAsset
RoomDatabase.Builder.createFromFile
RoomDatabase.Builder.createFromInputStream
RoomDatabase.PrepackagedDatabaseCallback
Room'un gelecekteki bir sürümünde önceden paketlenmiş veritabanları için destek eklemeyi planlıyoruz.
Çoklu Örnek Geçersiz Kılma
Çok örnekli geçersiz kılmayı etkinleştiren API olan RoomDatabase.Builder.enableMultiInstanceInvalidation
yalnızca Android'de kullanılabilir, ortak platformlarda veya diğer platformlarda kullanılamaz.