Menyimpan data di database lokal menggunakan Room   Bagian dari Android Jetpack.

Coba dengan Multiplatform Kotlin
Multiplatform Kotlin memungkinkan berbagi lapisan database dengan platform lain. Pelajari cara menyiapkan dan menggunakan Database Room di KMP

Aplikasi yang menangani data terstruktur dalam jumlah sangat banyak akan sangat terbantu jika data tersebut disimpan secara lokal. Kasus penggunaan yang paling umum adalah menyimpan bagian data yang relevan ke dalam cache sehingga jika perangkat tidak dapat mengakses jaringan, pengguna masih dapat menjelajahi konten tersebut meskipun offline.

Library persistensi Room menyediakan layer abstraksi atas SQLite untuk memungkinkan akses database yang lancar sambil memanfaatkan kemampuan penuh SQLite. Secara khusus, Room memberikan manfaat berikut:

  • Verifikasi waktu kompilasi kueri SQL.
  • Anotasi praktis yang meminimalkan kode boilerplate muncul berulang kali dan rentan error.
  • Jalur migrasi database sederhana.

Sebaiknya gunakan Room dan jangan menggunakan SQLite API secara langsung.

Penyiapan

Untuk menggunakan Room di aplikasi Anda, tambahkan dependensi berikut ke file build.gradle.kts modul. Room 3.0 memerlukan KSP untuk pemrosesan anotasi.

Kotlin

dependencies {
    val room_version = "3.0.0"

    implementation("androidx.room3:room3-runtime:$room_version")
    ksp("androidx.room3:room3-compiler:$room_version")
}

Groovy

dependencies {
    def room_version = "3.0.0"

    implementation "androidx.room3:room3-runtime:$room_version"

    ksp "androidx.room3:room3-compiler:$room_version"
}

Komponen utama

Terdapat tiga komponen utama dalam Room:

  • Class database yang menyimpan database dan berfungsi sebagai titik akses utama bagi koneksi saat ini ke data persisten aplikasi Anda.
  • Entity data yang menampilkan tabel di database aplikasi Anda.
  • Objek akses data (DAO) yang menyediakan fungsi agar aplikasi dapat membuat kueri, mengupdate, memasukkan, dan menghapus data dalam database.

Class database menyediakan aplikasi Anda dengan instance DAO yang terkait dengan database tersebut. Selanjutnya, aplikasi dapat menggunakan DAO untuk mengambil data dari database sebagai instance dari objek entity data terkait. Aplikasi juga dapat menggunakan entity data yang ditentukan untuk memperbarui baris dari tabel yang sesuai atau membuat baris baru untuk penyisipan. Gambar 1 mengilustrasikan hubungan antara berbagai komponen Room.

Gambar 1. Diagram arsitektur library Room.

Contoh implementasi

Bagian ini menampilkan contoh implementasi database Room dengan satu entity data dan satu DAO.

Entity data

Kode berikut menentukan entity data User. Setiap instance User mewakili baris dalam tabel user di database aplikasi.

@Entity
data class User(
    @PrimaryKey val uid: Int,
    @ColumnInfo(name = "first_name") val firstName: String,
    @ColumnInfo(name = "last_name") val lastName: String
)

Untuk mempelajari entity data di Room lebih lanjut, lihat Menentukan data menggunakan entity Room.

Objek akses data (DAO)

Kode berikut menentukan DAO yang disebut UserDao. UserDao menyediakan fungsi yang digunakan aplikasi lain untuk berinteraksi dengan data dalam tabel user.

@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    suspend fun getAll(): List<User>

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    suspend fun loadAllByIds(userIds: IntArray): List<User>

    @Query(
        """
        SELECT * FROM user
        WHERE first_name LIKE :first AND last_name LIKE :last LIMIT 1
        """
    )
    suspend fun findByName(first: String, last: String): User

    @Insert
    suspend fun insertAll(vararg users: User)

    @Delete
    suspend fun delete(user: User)
}

Untuk mempelajari DAO lebih lanjut, lihat Mengakses data menggunakan Room DAO.

Database

Kode berikut menentukan class AppDatabase untuk menyimpan database. AppDatabase menentukan konfigurasi database dan berfungsi sebagai titik akses (AP) utama aplikasi ke data yang bertahan. Class database harus memenuhi kondisi berikut:

  • Class harus dianotasi dengan anotasi @Database yang menyertakan array entities yang mencantumkan semua entity data yang terkait dengan database.
  • Class harus berupa class abstrak yang memperluas RoomDatabase.
  • Untuk setiap class DAO yang terkait dengan database, class database harus menentukan fungsi abstrak yang tidak memerlukan argumen dan menampilkan instance class DAO.

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Catatan: Jika aplikasi Anda berjalan dalam satu proses, ikuti pola desain singleton saat membuat instance objek AppDatabase object. Setiap instance RoomDatabase cukup mahal, dan Anda tidak selalu memerlukan akses ke beberapa instance dalam satu proses.

Jika aplikasi berjalan dalam beberapa proses, sertakan enableMultiInstanceInvalidation() pada pemanggilan builder database Anda. Dengan demikian, jika instance AppDatabase disertakan dalam setiap proses, Anda dapat membatalkan file database bersama dalam satu proses dan pembatalan ini akan otomatis disebarkan ke instance AppDatabase dalam proses lainnya.

Penggunaan

Setelah menentukan entity data, DAO, dan objek database, Anda dapat menggunakan kode berikut untuk membuat instance database:

val db =
    Room.databaseBuilder<AppDatabase>(applicationContext, "database-name")
        .setDriver(AndroidSQLiteDriver())
        .build()

Kemudian, Anda dapat menggunakan fungsi abstrak dari AppDatabase untuk mendapatkan instance DAO. Selanjutnya, Anda dapat menggunakan fungsi dari instance DAO untuk berinteraksi dengan database:

val userDao = db.userDao()
val users: List<User> = userDao.getAll()

Referensi lainnya

Untuk mempelajari Room lebih lanjut, lihat referensi tambahan berikut.

Contoh