Oda kalıcılık kitaplığı, izin vermek için SQLite üzerinde bir soyutlama katmanı sağlar ile daha güçlü veritabanı erişimi sunar ve SQLite'ın tam gücünden yararlanır. Bu Bu sayfada, Kotlin Multiplatform (KMP) projelerinde Room'un kullanımıyla ilgili bilgiler yer almaktadır. Daha fazla Odayı kullanmayla ilgili daha fazla bilgi için Odayı kullanarak verileri yerel veritabanına kaydetme başlıklı makaleye göz atın. veya resmi örneklerimizi kullanın.
Bağımlılıkları belirleme
Odanın KMP'yi destekleyen mevcut sürümü: 2.7.0-alpha01 veya sonraki sürümler.
KMP projenizde Room (Oda) ayarlarını yapmak için
Modülünüz için build.gradle.kts
dosyası:
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ı bölümüandroidx.sqlite:sqlite-bundled
- (İsteğe bağlı) Paket halinde sunulan SQLite kitaplığı
Ayrıca, Odanın SQLite sürücüsünü yapılandırmanız gerekir. Bu sürücüler farklı tercih edebilirsiniz. Görüntüleyin Sürücü uygulamaları inceleyebilirsiniz.
Ek kurulum bilgileri için aşağıdakilere bakın:
- Oda Gradle Eklentisini kullanarak şema konumunu ayarlayın.
- Kotlin Multiplatform ile KSP.
- Çalışma zamanı bağımlılıkları ekleme.
Veritabanı sınıflarını tanımlama
DAO'larla birlikte @Database
ek açıklamalı bir veritabanı sınıfı oluşturmanız gerekir.
ve ortak KMP modülünüzün ortak kaynak kümesindeki varlıklar için geçerlidir. Yerleştirme
ortak kaynaklarda yer alan bu sınıflar,
tüm hedeflerde paylaşılmasına olanak tanır.
platformlar.
Arayüzde expect
nesnesi belirttiğinizde
RoomDatabaseConstructor
, Oda derleyicisi actual
oluşturur
hakkında bilgi edindiniz. Android Studio bir uyarı gönderebilir
"Expected object 'AppDatabaseConstructor' has no actual declaration in module";
you can suppress the warning with
@Suppress("NO_ACTUAL_FOR_EXPECT")".
// shared/src/commonMain/kotlin/Database.kt
@Database(entities = [TodoEntity::class], version = 1)
@ConstructedBy(AppDatabaseConstructor::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun getDao(): TodoDao
}
// The Room compiler generates the `actual` implementations.
@Suppress("NO_ACTUAL_FOR_EXPECT")
expect object AppDatabaseConstructor : RoomDatabaseConstructor<AppDatabase>
@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
)
İsterseniz gerçek / beklenen beyanları da kullanabilirsiniz.
oda uygulamaları oluşturabilirsiniz. Örneğin, Arkadaş Bitkiler uygulamasına bir
expect
ve ardından kullanılarak ortak kodda tanımlanan platforma özel DAO
platforma özgü ek sorgularla birlikte actual
tanımlarını belirtin
kaynak kümeleridir.
Veritabanı oluşturucuyu oluşturma
Her platformda Oda örneğini oluşturmak için bir veritabanı oluşturucu tanımlamanız gerekir. Bu
API'nin platforma özgü kaynakta olması gereken tek bölümüdür
farklı kümelere sahip URL'ler oluşturabilirsiniz. Örneğin, Android'de
konum bilgisi genellikle
Context.getDatabasePath()
API, iOS'te ise veritabanı konumu şöyledir:
NSFileManager
kullanılarak elde edilebilir.
Android
Veritabanı örneğini oluşturmak için veritabanıyla birlikte bir Bağlam bilgisi belirtin yol'a dokunun.
// 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ğini oluşturmak için
NSFileManager
, genellikle NSDocumentDirectory
konumunda bulunur.
// shared/src/iosMain/kotlin/Database.kt
fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
val dbFilePath = documentDirectory() + "/my_room.db"
return Room.databaseBuilder<AppDatabase>(
name = dbFilePath,
)
}
private fun documentDirectory(): String {
val documentDirectory = NSFileManager.defaultManager.URLForDirectory(
directory = NSDocumentDirectory,
inDomain = NSUserDomainMask,
appropriateForURL = null,
create = false,
error = null,
)
return requireNotNull(documentDirectory?.path)
}
JVM (Masaüstü)
Veritabanı örneği oluşturmak için Java veya Kotlin kullanarak veritabanı yolu sağlayın API'ler.
// shared/src/jvmMain/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ı örneklendirmesi
Platforma özgü uygulamaların birinden RoomDatabase.Builder
aldıktan sonra
varsa, Room veritabanının geri kalanını ortak bir kodda
örneklemlendirme ile birlikte kullanabilirsiniz.
// 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'leri BundledSQLiteDriver
kullanıyor. Bu,
Kaynaktan derlenen SQLite'ı içeren önerilen sürücüyü
tüm platformlarda SQLite'ın en tutarlı ve güncel sürümünü sunar. Şu durumda:
işletim sistemi tarafından sağlanan SQLite'ı kullanmak istiyorsanız setDriver
API'yi platforma özel olarak kullanın
kaynak kümeleridir. Android'de,
AndroidSQLiteDriver
, iOS'te NativeSQLiteDriver
kullanabilirsiniz. Alıcı:
NativeSQLiteDriver
kullanıyorsanız iOS'in değiştirebilmesi için bir bağlayıcı seçeneği
SQLit sistemine dinamik olarak bağlanır.
// 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
Oda, ilk başta bir Android kitaplığı olarak geliştirilmiş ve daha sonra API uyumluluğuna odaklanan KMP. Room'un KMP sürümü biraz farklıdır. Android'e özel sürümden fark yaratıyor. Bu farklılıklar aşağıda açıklandığı gibi listelenip açıklaması gerekir.
DAO işlevlerini engelleme
Room for KMP kullanılırken Android dışı platformlar için derlenen tüm DAO işlevleri
şunun reaktif dönüş türleri hariç olmak üzere suspend
işlevleri olması gerekir:
Flow
olarak.
// 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() { // … }
}
Zengin özelliklere sahip eşzamansız kotlinx.coroutines
kitaplığının sunduğu avantajlar
üç platforma ulaşabilirsiniz. Optimum işlevsellik için suspend
işlevleri hariç olmak üzere, KMP projesinde derlenen DAO'lar için
Mevcut
kullanabilirsiniz.
KMP ile özellik farklılıkları
Bu bölümde, KMP ve Android platformu arasındaki özelliklerin farkı açıklanmaktadır. oda sürümleridir.
@RawQuery DAO işlevleri
Android dışı platformlar için derlenen, @RawQuery
ile ek açıklama eklenen işlevler
yerine RoomRawQuery
türünde bir parametre tanımlaması gerekir
SupportSQLiteQuery
.
@Dao
interface TodoDao {
@RawQuery
suspend fun getTodos(query RoomRawQuery): List<TodoEntity>
}
Çalışma zamanında sorgu oluşturmak için RoomRawQuery
kullanılabilir:
suspend fun getTodosWithLowercaseTitle(title: String): List<TodoEntity> {
val query = RoomRawQuery(
sql = "SELECT * FROM TodoEntity WHERE title = ?"
onBindStatement = {
it.bindText(1, title.lowercase())
}
)
return todosDao.getTodos(query)
}
Sorgu Geri Çağırması
Sorgu geri çağırmalarının yapılandırılmasına yönelik aşağıdaki API'ler, yaygın olarak kullanılmamaktadır ve Android dışındaki platformlarda kullanılamaz.
RoomDatabase.Builder.setQueryCallback
RoomDatabase.QueryCallback
Odanın gelecekteki bir sürümünde geri arama için destek sunmayı planlıyoruz.
Sorgu geri çağırma özelliğiyle RoomDatabase
yapılandırma API'si
Geri çağırma arayüzüyle birlikte RoomDatabase.Builder.setQueryCallback
RoomDatabase.QueryCallback
ortak olarak kullanılamadığı için kullanılamıyor
diğer platformlarda da kullanılabilir.
Veritabanını Otomatik Kapatma
Zaman aşımından sonra otomatik kapanmayı etkinleştiren API,
RoomDatabase.Builder.setAutoCloseTimeout
yalnızca Android'de kullanılabilir ve
diğer platformlarda kullanılamıyor.
Önceden Paketlenmiş Veritabanı
Mevcut bir veritabanını (ör.RoomDatabase
veri tabanı) ortak olarak mevcut değildir ve bu nedenle
Android dışındaki platformlarda çalışabilirsiniz. Bu API'ler şunlardır:
RoomDatabase.Builder.createFromAsset
RoomDatabase.Builder.createFromFile
RoomDatabase.Builder.createFromInputStream
RoomDatabase.PrepackagedDatabaseCallback
Gelecekteki bir sürüme, kullanıma hazır veritabanları için destek sunmayı planlıyoruz Oda.
Çoklu Örnek Geçersiz Kılma
Çoklu örneği geçersiz kılmayı sağlayan API,
RoomDatabase.Builder.enableMultiInstanceInvalidation
şuralarda kullanılabilir:
Android'dir ve yaygın olarak veya diğer platformlarda kullanılamaz.