Menentukan data menggunakan entity Room

Saat menggunakan library persistensi Room untuk menyimpan data aplikasi, Anda menentukan entity untuk mewakili objek yang ingin disimpan. Setiap entity sesuai dengan tabel dalam database Room yang terkait, dan setiap instance entity mewakili baris data dalam tabel yang sesuai.

Artinya, Anda dapat menggunakan entity Room untuk menentukan skema database tanpa menulis kode SQL apa pun.

Anatomi entity

Anda menentukan setiap entity Room sebagai class yang dianotasikan dengan @Entity. Entity Room menyertakan kolom untuk setiap kolom dalam tabel yang sesuai di database, termasuk satu atau beberapa kolom yang membentuk kunci utama.

Kode berikut adalah contoh entity sederhana yang menentukan tabel User dengan kolom untuk ID, nama depan, dan nama belakang:

Kotlin

@Entity
data class User(
    @PrimaryKey val id: Int,

    val firstName: String?,
    val lastName: String?
)

Java

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

    public String firstName;
    public String lastName;
}

Secara default, Room menggunakan nama class sebagai nama tabel database. Jika Anda ingin tabel memiliki nama yang berbeda, tetapkan properti tableName anotasi @Entity. Demikian pula, Room menggunakan nama kolom sebagai nama kolom dalam database secara default. Jika Anda ingin kolom memiliki nama yang berbeda, tambahkan anotasi @ColumnInfo ke kolom dan setel properti name. Contoh berikut menunjukkan nama-nama kustom untuk tabel dan kolomnya:

Kotlin

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

Java

@Entity(tableName = "users")
public class User {
    @PrimaryKey
    public int id;

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

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

Menentukan kunci utama

Setiap entity Room harus menentukan kunci utama yang mengidentifikasi setiap baris secara unik dalam tabel database yang sesuai. Cara paling langsung dalam melakukannya adalah dengan menganotasi satu kolom dengan @PrimaryKey:

Kotlin

@PrimaryKey val id: Int

Java

@PrimaryKey
public int id;

Menentukan kunci utama gabungan

Jika memerlukan instance entity untuk diidentifikasi secara unik dengan kombinasi beberapa kolom, Anda dapat menentukan kunci utama gabungan dengan mencantumkan kolom tersebut di properti primaryKeys dari @Entity:

Kotlin

@Entity(primaryKeys = ["firstName", "lastName"])
data class User(
    val firstName: String?,
    val lastName: String?
)

Java

@Entity(primaryKeys = {"firstName", "lastName"})
public class User {
    public String firstName;
    public String lastName;
}

Mengabaikan kolom

Secara default, Room akan membuat kolom bagi setiap kolom yang ditentukan dalam entity. Jika entity memiliki kolom yang tidak ingin dipertahankan, anotasikan kolom menggunakan @Ignore, seperti yang ditunjukkan dalam cuplikan kode berikut:

Kotlin

@Entity
data class User(
    @PrimaryKey val id: Int,
    val firstName: String?,
    val lastName: String?,
    @Ignore val picture: Bitmap?
)

Java

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

    public String firstName;
    public String lastName;

    @Ignore
    Bitmap picture;
}

Jika suatu entity mewarisi kolom dari parent entity, biasanya akan lebih mudah untuk menggunakan properti ignoredColumns dari atribut @Entity:

Kotlin

open class User {
    var picture: Bitmap? = null
}

@Entity(ignoredColumns = ["picture"])
data class RemoteUser(
    @PrimaryKey val id: Int,
    val hasVpn: Boolean
) : User()

Java

@Entity(ignoredColumns = "picture")
public class RemoteUser extends User {
    @PrimaryKey
    public int id;

    public boolean hasVpn;
}

Room mendukung beberapa jenis anotasi yang memudahkan Anda menelusuri detail dalam tabel database. Gunakan penelusuran teks lengkap kecuali minSdkVersion aplikasi Anda kurang dari 16.

Mendukung penelusuran teks lengkap

Jika aplikasi Anda memerlukan akses yang sangat cepat ke informasi database melalui penelusuran teks lengkap (FTS), atur agar entity Anda didukung oleh tabel virtual yang menggunakan modul ekstensi SQLite FTS3 atau FTS4. Untuk menggunakan kemampuan ini, (tersedia di Room 2.1.0 dan yang lebih tinggi), tambahkan anotasi @Fts3 atau @Fts4 ke entity yang ditentukan, seperti yang ditunjukkan dalam cuplikan kode berikut:

Kotlin

// Use `@Fts3` only if your app has strict disk space requirements or if you
// require compatibility with an older SQLite version.
@Fts4
@Entity(tableName = "users")
data class User(
    /* Specifying a primary key for an FTS-table-backed entity is optional, but
       if you include one, it must use this type and column name. */
    @PrimaryKey @ColumnInfo(name = "rowid") val id: Int,
    @ColumnInfo(name = "first_name") val firstName: String?
)

Java

// Use `@Fts3` only if your app has strict disk space requirements or if you
// require compatibility with an older SQLite version.
@Fts4
@Entity(tableName = "users")
public class User {
    // Specifying a primary key for an FTS-table-backed entity is optional, but
    // if you include one, it must use this type and column name.
    @PrimaryKey
    @ColumnInfo(name = "rowid")
    public int id;

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

Jika tabel mendukung konten dalam berbagai bahasa, gunakan opsi languageId untuk menentukan kolom yang menyimpan informasi bahasa bagi setiap baris:

Kotlin

@Fts4(languageId = "lid")
@Entity(tableName = "users")
data class User(
    // ...
    @ColumnInfo(name = "lid") val languageId: Int
)

Java

@Fts4(languageId = "lid")
@Entity(tableName = "users")
public class User {
    // ...

    @ColumnInfo(name = "lid")
    int languageId;
}

Room menyediakan beberapa opsi lain untuk menentukan entity yang didukung FTS, termasuk pengurutan hasil, jenis tokenizer, dan tabel yang dikelola sebagai konten eksternal. Untuk detail selengkapnya tentang opsi ini, lihat referensi FtsOptions.

Mengindeks kolom spesifik

Jika aplikasi Anda harus mendukung versi SDK yang tidak mendukung entity yang didukung oleh tabel FTS3 atau FTS4, Anda masih dapat mengindeks kolom tertentu dalam database untuk mempercepat kueri. Untuk menambahkan indeks pada entity, sertakan properti indices dalam anotasi @Entity, dengan mencantumkan nama kolom yang ingin disertakan pada indeks atau indeks komposit. Cuplikan kode berikut menunjukkan proses anotasi ini:

Kotlin

@Entity(indices = [Index(value = ["last_name", "address"])])
data class User(
    @PrimaryKey val id: Int,
    val firstName: String?,
    val address: String?,
    @ColumnInfo(name = "last_name") val lastName: String?,
    @Ignore val picture: Bitmap?
)

Java

@Entity(indices = {@Index("name"),
        @Index(value = {"last_name", "address"})})
public class User {
    @PrimaryKey
    public int id;

    public String firstName;
    public String address;

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

    @Ignore
    Bitmap picture;
}

Terkadang, kolom atau grup kolom tertentu dalam database harus bersifat unik. Anda dapat menerapkan properti keunikan ini dengan menetapkan properti unique dari anotasi @Index ke true. Contoh kode berikut mencegah tabel memiliki dua baris yang berisi kumpulan nilai yang sama untuk kolom firstName dan lastName:

Kotlin

@Entity(indices = [Index(value = ["first_name", "last_name"],
        unique = true)])
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "last_name") val lastName: String?,
    @Ignore var picture: Bitmap?
)

Java

@Entity(indices = {@Index(value = {"first_name", "last_name"},
        unique = true)})
public class User {
    @PrimaryKey
    public int id;

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

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

    @Ignore
    Bitmap picture;
}

Menyertakan objek berbasis AutoValue

Pada Room 2.1.0 dan yang lebih tinggi, Anda dapat menggunakan class nilai tetap berbasis Java, yang dianotasikan menggunakan @AutoValue, sebagai entity dalam database aplikasi Anda. Dukungan ini sangat berguna saat dua instance dari satu entity dianggap sama jika kolomnya berisi nilai yang sama.

Saat menggunakan class yang dianotasikan dengan @AutoValue sebagai entity, Anda dapat menganotasikan metode abstrak class menggunakan @PrimaryKey, @ColumnInfo, @Embedded, dan @Relation. Namun, saat menggunakan anotasi ini, Anda harus selalu menyertakan anotasi @CopyAnnotations agar Room dapat dengan benar menginterpretasikan penerapan yang dihasilkan otomatis oleh metode.

Cuplikan kode berikut memberikan contoh class yang dianotasikan dengan @AutoValue yang dikenali oleh Room sebagai entity:

User.java

@AutoValue
@Entity
public abstract class User {
    // Supported annotations must include `@CopyAnnotations`.
    @CopyAnnotations
    @PrimaryKey
    public abstract long getId();

    public abstract String getFirstName();
    public abstract String getLastName();

    // Room uses this factory method to create User objects.
    public static User create(long id, String firstName, String lastName) {
        return new AutoValue_User(id, firstName, lastName);
    }
}