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

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.

Karena pertimbangan ini, Anda disarankan menggunakan Room dan jangan menggunakan SQLite API secara langsung.

Penyiapan

Untuk menggunakan Room di aplikasi Anda, tambahkan dependensi berikut ke file build.gradle aplikasi Anda.

Kotlin

dependencies {
    val room_version = "2.6.1"

    implementation("androidx.room:room-runtime:$room_version")

    // If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP)
    // See Add the KSP plugin to your project
    ksp("androidx.room:room-compiler:$room_version")

    // If this project only uses Java source, use the Java annotationProcessor
    // No additional plugins are necessary
    annotationProcessor("androidx.room:room-compiler:$room_version")

    // optional - Kotlin Extensions and Coroutines support for Room
    implementation("androidx.room:room-ktx:$room_version")

    // optional - RxJava2 support for Room
    implementation("androidx.room:room-rxjava2:$room_version")

    // optional - RxJava3 support for Room
    implementation("androidx.room:room-rxjava3:$room_version")

    // optional - Guava support for Room, including Optional and ListenableFuture
    implementation("androidx.room:room-guava:$room_version")

    // optional - Test helpers
    testImplementation("androidx.room:room-testing:$room_version")

    // optional - Paging 3 Integration
    implementation("androidx.room:room-paging:$room_version")
}

Groovy

dependencies {
    def room_version = "2.6.1"

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

    // If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP)
    // See KSP Quickstart to add KSP to your build
    ksp "androidx.room:room-compiler:$room_version"

    // If this project only uses Java source, use the Java annotationProcessor
    // No additional plugins are necessary
    annotationProcessor "androidx.room:room-compiler:$room_version"

    // optional - RxJava2 support for Room
    implementation "androidx.room:room-rxjava2:$room_version"

    // optional - RxJava3 support for Room
    implementation "androidx.room:room-rxjava3:$room_version"

    // optional - Guava support for Room, including Optional and ListenableFuture
    implementation "androidx.room:room-guava:$room_version"

    // optional - Test helpers
    testImplementation "androidx.room:room-testing:$room_version"

    // optional - Paging 3 Integration
    implementation "androidx.room:room-paging:$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 berbagai metode 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.

Kotlin

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

Java

@Entity
public class User {
    @PrimaryKey
    public int uid;

    @ColumnInfo(name = "first_name")
    public String firstName;

    @ColumnInfo(name = "last_name")
    public String lastName;
}

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 metode yang digunakan aplikasi lain untuk berinteraksi dengan data dalam tabel user.

Kotlin

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

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

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

    @Insert
    fun insertAll(vararg users: User)

    @Delete
    fun delete(user: User)
}

Java

@Dao
public interface UserDao {
    @Query("SELECT * FROM user")
    List<User> getAll();

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    List<User> loadAllByIds(int[] userIds);

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

    @Insert
    void insertAll(User... users);

    @Delete
    void delete(User user);
}

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

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 metode abstrak yang memiliki nol argumen dan menampilkan instance class DAO.

Kotlin

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

Java

@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
}

Catatan: Jika aplikasi Anda berjalan dalam satu proses, ikuti pola desain singleton saat membuat instance objek AppDatabase. 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:

Kotlin

val db = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java, "database-name"
        ).build()

Java

AppDatabase db = Room.databaseBuilder(getApplicationContext(),
        AppDatabase.class, "database-name").build();

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

Kotlin

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

Java

UserDao userDao = db.userDao();
List<User> users = userDao.getAll();

Referensi lainnya

Untuk mempelajari Room lebih lanjut, lihat referensi tambahan berikut.

Contoh

Codelab

Blog