Room 永続ライブラリを使用する場合、関連するフィールドのセットをエンティティとして定義します。エンティティごとに、関連付けられた Database
オブジェクト内にテーブルが作成され、アイテムが格納されます。エンティティ クラスは、Database
クラス内の entities
配列で参照する必要があります。
エンティティを定義する方法を次のコード スニペットに示します。
Kotlin
@Entity data class User( @PrimaryKey var id: Int, var firstName: String?, var lastName: String? )
Java
@Entity public class User { @PrimaryKey public int id; public String firstName; public String lastName; }
フィールドを永続化するには、Room がそのフィールドにアクセスできる必要があります。フィールドを公開したり、そのゲッターやセッターを指定したりすることができます。getter メソッドや setter メソッドを使用する場合は、Room の JavaBeans 規則に基づきます。
主キーを使用する
各エンティティは、少なくとも 1 つのフィールドを主キーとして定義する必要があります。フィールドが 1 つしかない場合でも、そのフィールドに @PrimaryKey
アノテーションを付ける必要があります。また、Room によって自動 ID をエンティティに割り当てる場合は、@PrimaryKey
の autoGenerate
プロパティを設定します。エンティティが複合主キーを持つ場合は、@Entity
アノテーションの primaryKeys
プロパティを使用します。次のコード スニペットをご覧ください。
Kotlin
@Entity(primaryKeys = arrayOf("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; }
デフォルトでは、Room はクラス名をデータベース テーブル名として使用します。テーブルに別の名前を付ける場合は、@Entity
アノテーションの tableName
プロパティを設定します。次のコード スニペットをご覧ください。
Kotlin
@Entity(tableName = "users") data class User ( // ... )
Java
@Entity(tableName = "users") public class User { // ... }
注: SQLite のテーブル名では、大文字と小文字が区別されません。
tableName
プロパティと同様、Room はフィールド名をデータベースの列名として使用します。列に別の名前を付ける場合は、@ColumnInfo
アノテーションをフィールドに追加します。次のコード スニペットをご覧ください。
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; }
フィールドを無視する
デフォルトでは、Room はエンティティ内で定義されているフィールドごとに列を作成します。
エンティティ内に永続化しないフィールドがある場合は、@Ignore
を使用して対象フィールドにアノテーションを付けます。次のコード スニペットをご覧ください。
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; }
エンティティが親エンティティからフィールドを継承している場合、通常は @Entity
属性の ignoredColumns
プロパティを使用する方が簡単です。
Kotlin
open class User { var picture: Bitmap? = null } @Entity(ignoredColumns = arrayOf("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 は、データベースのテーブル内の詳細情報を簡単に検索できるように、さまざまなタイプのアノテーションをサポートしています。アプリの minSdkVersion
が 16 未満でなければ、全文検索を利用できます。
全文検索をサポートする
全文検索(FTS)を通じてデータベース情報に迅速にアクセスする必要があるアプリの場合、FTS3 または FTS4 の SQLite 拡張モジュールを使用した仮想テーブルで、エンティティをバックアップします。Room 2.1.0 以降で利用可能なこの機能を使用するには、対象エンティティに @Fts3
または @Fts4
のアノテーションを追加します。次のコード スニペットをご覧ください。
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; }
テーブルが複数の言語のコンテンツをサポートしている場合は、languageId
オプションを使用して、各行の言語情報を格納する列を指定します。
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 には、結果の順序化や、トークナイザー型、外部コンテンツとして管理されるテーブルなど、FTS バックアップ型エンティティを定義するためのオプションが幅広く用意されています。各オプションの詳細については、FtsOptions
リファレンスをご覧ください。
特定の列をインデックスに登録する
FTS3 / FTS4 テーブル バックアップ型エンティティを使用できない SDK バージョンをサポートする必要があるアプリの場合は、データベース内の特定の列をインデックスに登録することで、クエリを高速化できます。エンティティにインデックスを追加するには、@Entity
アノテーション内に indices
プロパティを追加して、インデックスまたは複合インデックスに登録する列の名前をリストアップします。このアノテーション プロセスを実行するコード スニペットを以下に示します。
Kotlin
@Entity(indices = arrayOf(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; }
データベース内の特定のフィールドやフィールド グループを一意にすることが必要となる場合があります。
この一意性プロパティを適用するには、@Index
アノテーションの unique
プロパティを true
に設定します。firstName
列と lastName
列に対して同一の値セットを持つ 2 つの行がテーブル内に存在しないようにする例を次のサンプルコードに示します。
Kotlin
@Entity(indices = arrayOf(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; }
AutoValue ベースのオブジェクトを含める
Room 2.1.0 以降では、@AutoValue
を使用してアノテーションを付けることで、Java ベースの不変値クラスを、アプリのデータベース内のエンティティとして使用できます。この機能は特に、「エンティティの 2 つのインスタンスに関して、列に同じ値が格納されている場合は等しいと見なす」というケースで役立ちます。
@AutoValue
アノテーションの付いたクラスをエンティティとして使用する場合、@PrimaryKey
、@ColumnInfo
、@Embedded
、@Relation
を使用してクラスの抽象メソッドにアノテーションを付けることができます。ただし、このようなアノテーションを使用する場合は、メソッドの自動生成実装を Room が適切に解釈できるように、毎回 @CopyAnnotations
アノテーションを含める必要があります。
Room がエンティティとして認識できる @AutoValue
アノテーション付きクラスの例を次のコード スニペットに示します。
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); } }