Library persistensi Room menyediakan lapisan abstraksi pada SQLite untuk memungkinkan akses database yang lebih andal sekaligus memanfaatkan kemampuan penuh SQLite. Halaman ini berfokus pada penggunaan Room dalam project Multiplatform (KMP) Kotlin. Untuk mengetahui informasi selengkapnya tentang penggunaan Room, lihat Menyimpan data di database lokal menggunakan Room atau contoh resmi kami.
Menyiapkan dependensi
Versi Room saat ini yang mendukung KMP adalah 2.7.0-alpha01 atau yang lebih tinggi.
Untuk menyiapkan Room di project KMP, tambahkan dependensi untuk artefak dalam
file build.gradle.kts
untuk modul Anda:
androidx.room:room-gradle-plugin
- Plugin Gradle untuk mengonfigurasi skema Roomandroidx.room:room-compiler
- Prosesor KSP yang menghasilkan kodeandroidx.room:room-runtime
- Bagian runtime libraryandroidx.sqlite:sqlite-bundled
- (Opsional) Library SQLite yang dipaketkan
Selain itu, Anda perlu mengonfigurasi driver SQLite Room. Driver ini berbeda-beda berdasarkan platform target. Lihat Implementasi driver untuk deskripsi implementasi driver yang tersedia.
Untuk informasi penyiapan tambahan, lihat referensi berikut:
- Tetapkan lokasi skema menggunakan Plugin Room Gradle.
- KSP dengan Multiplatform Kotlin.
- Menambahkan dependensi runtime.
Menentukan class database
Anda harus membuat class database yang dianotasi dengan @Database
beserta DAO
dan entity di dalam set sumber umum modul KMP bersama. Menempatkan
class ini di sumber yang sama akan memungkinkan class tersebut dibagikan di semua platform
target.
// 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
)
Perhatikan bahwa Anda dapat menggunakan deklarasi aktual / mengharapkan untuk membuat
implementasi Room khusus platform. Misalnya, Anda dapat menambahkan
DAO khusus platform yang ditentukan dalam kode umum menggunakan expect
, lalu
menentukan definisi actual
dengan kueri tambahan di set sumber
khusus platform.
Membuat builder database
Anda perlu menentukan builder database untuk membuat instance Room di setiap platform. Ini
adalah satu-satunya bagian dari API yang harus berada dalam set sumber
khusus platform karena perbedaan dalam API sistem file. Misalnya, di Android, lokasi database biasanya diperoleh melalui Context.getDatabasePath()
API, sedangkan untuk iOS, lokasi database diperoleh menggunakan NSHomeDirectory
.
Android
Untuk membuat instance database, tentukan Context beserta jalur database. Anda tidak perlu menetapkan factory database.
// 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
Untuk membuat instance database, sediakan factory database beserta jalur database. Factory database adalah fungsi lambda yang memanggil
fungsi ekstensi yang dihasilkan yang namanya instantiateImpl
dengan penerima
jenis KClass<T>
, dengan T
adalah jenis class yang dianotasi @Database
.
// 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 (Desktop)
Untuk membuat instance database, tentukan hanya jalur database-nya. Anda tidak perlu menyediakan factory {i>database<i}.
// 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,
)
}
Pembuatan instance database
Setelah mendapatkan RoomDatabase.Builder
dari salah satu konstruktor khusus
platform, Anda dapat mengonfigurasi database Room lainnya dalam kode umum
beserta pembuatan instance database yang sebenarnya.
// shared/src/commonMain/kotlin/Database.kt
fun getRoomDatabase(
builder: RoomDatabase.Builder<AppDatabase>
): AppDatabase {
return builder
.addMigrations(MIGRATIONS)
.fallbackToDestructiveMigrationOnDowngrade()
.setDriver(BundledSQLiteDriver())
.setQueryCoroutineContext(Dispatchers.IO)
.build()
}
Memilih SQLiteDriver
Cuplikan kode sebelumnya menggunakan BundledSQLiteDriver
. Ini adalah
driver yang direkomendasikan, yang menyertakan SQLite dari sumber, yang menyediakan
versi SQLite terbaru dan paling konsisten di semua platform. Jika Anda
ingin menggunakan SQLite yang disediakan OS, gunakan setDriver
API di set sumber
khusus platform yang menentukan driver khusus platform. Untuk Android, Anda dapat menggunakan AndroidSQLiteDriver
, sedangkan untuk iOS, Anda dapat menggunakan NativeSQLiteDriver
. Untuk
menggunakan NativeSQLiteDriver
, Anda harus menyediakan opsi penaut agar aplikasi iOS
ditautkan secara dinamis dengan SQLite sistem.
// 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")
}
}
}
Perbedaan
Room awalnya dikembangkan sebagai library Android dan kemudian dimigrasikan ke KMP dengan fokus pada kompatibilitas API. Versi KMP Room agak berbeda antara platform dan versi khusus Android. Perbedaan ini dicantumkan dan dijelaskan sebagai berikut.
Memblokir fungsi DAO
Saat menggunakan Room untuk KMP, semua fungsi DAO yang dikompilasi untuk platform non-Android
harus berupa fungsi suspend
dengan pengecualian jenis nilai yang ditampilkan reaktif, seperti
Flow
.
// 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() { // … }
}
Room mendapatkan manfaat dari library kotlinx.coroutines
asinkron kaya fitur yang ditawarkan Kotlin untuk berbagai platform. Untuk fungsionalitas yang optimal, fungsi suspend
diterapkan untuk DAO yang dikompilasi dalam project KMP, dengan pengecualian
DAO khusus Android guna mempertahankan kompatibilitas mundur dengan codebase
yang sudah ada.
Perbedaan fitur dengan KMP
Bagian ini menjelaskan perbedaan fitur antara Room versi KMP dan platform Android.
Fungsi DAO @RawQuery
Fungsi yang dianotasi dengan @RawQuery
yang dikompilasi untuk platform non-Android akan menghasilkan error. Kami ingin menambahkan dukungan untuk @RawQuery
di
versi mendatang Room.
Callback Kueri
API berikut untuk mengonfigurasi callback kueri tidak tersedia secara umum, sehingga tidak tersedia di platform selain Android.
RoomDatabase.Builder.setQueryCallback
RoomDatabase.QueryCallback
Kami ingin menambahkan dukungan untuk callback kueri di Room versi mendatang.
API untuk mengonfigurasi RoomDatabase
dengan callback kueri RoomDatabase.Builder.setQueryCallback
beserta antarmuka callback RoomDatabase.QueryCallback
tidak tersedia secara umum, sehingga tidak tersedia di platform lain selain Android.
Menutup Database secara Otomatis
API untuk mengaktifkan penutupan otomatis setelah waktu tunggu,
RoomDatabase.Builder.setAutoCloseTimeout
, hanya tersedia di Android dan
tidak tersedia di platform lain.
Database dalam Paket
API berikut untuk membuat RoomDatabase
menggunakan database yang ada (yaitu database
dalam bentuk paket) tidak tersedia secara umum, sehingga tidak tersedia di
platform lain selain Android. API tersebut adalah:
RoomDatabase.Builder.createFromAsset
RoomDatabase.Builder.createFromFile
RoomDatabase.Builder.createFromInputStream
RoomDatabase.PrepackagedDatabaseCallback
Kami berencana menambahkan dukungan untuk database dalam bentuk paket di Room versi mendatang.
Pembatalan Multi-Instance
API untuk mengaktifkan pembatalan multi-instance
, RoomDatabase.Builder.enableMultiInstanceInvalidation
hanya tersedia di
Android dan tidak tersedia di platform umum atau platform lainnya.