Когда вы используете библиотеку постоянства комнаты для хранения данных вашего приложения, вы определяете сущности, представляющие объекты, которые вы хотите сохранить. Каждая сущность соответствует таблице в связанной базе данных Room, а каждый экземпляр сущности представляет строку данных в соответствующей таблице.
Это означает, что вы можете использовать сущности Room для определения схемы базы данных без написания кода SQL.
Анатомия сущности
Вы определяете каждую сущность Room как класс, аннотированный @Entity
. Сущность «Комната» включает поля для каждого столбца в соответствующей таблице базы данных, включая один или несколько столбцов, составляющих первичный ключ .
Следующий код представляет собой пример простой сущности, которая определяет таблицу User
со столбцами для идентификатора, имени и фамилии:
Котлин
@Entity data class User( @PrimaryKey val id: Int, val firstName: String?, val lastName: String? )
Ява
@Entity public class User { @PrimaryKey public int id; public String firstName; public String lastName; }
По умолчанию Room использует имя класса в качестве имени таблицы базы данных. Если вы хотите, чтобы таблица имела другое имя, установите свойство tableName
аннотации @Entity
. Аналогично, Room по умолчанию использует имена полей в качестве имен столбцов в базе данных. Если вы хотите, чтобы столбец имел другое имя, добавьте в поле аннотацию @ColumnInfo
и установите свойство name
. В следующем примере демонстрируются пользовательские имена для таблицы и ее столбцов:
Котлин
@Entity(tableName = "users") data class User ( @PrimaryKey val id: Int, @ColumnInfo(name = "first_name") val firstName: String?, @ColumnInfo(name = "last_name") val lastName: String? )
Ява
@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 должна определить первичный ключ , который однозначно идентифицирует каждую строку в соответствующей таблице базы данных. Самый простой способ сделать это — аннотировать один столбец с помощью @PrimaryKey
:
Котлин
@PrimaryKey val id: Int
Ява
@PrimaryKey public int id;
Определить составной первичный ключ
Если вам нужно, чтобы экземпляры сущности однозначно идентифицировались с помощью комбинации нескольких столбцов, вы можете определить составной первичный ключ , указав эти столбцы в свойстве primaryKeys
@Entity
:
Котлин
@Entity(primaryKeys = ["firstName", "lastName"]) data class User( val firstName: String?, val lastName: String? )
Ява
@Entity(primaryKeys = {"firstName", "lastName"}) public class User { public String firstName; public String lastName; }
Игнорировать поля
По умолчанию Room создает столбец для каждого поля, определенного в сущности. Если у сущности есть поля, которые вы не хотите сохранять, вы можете аннотировать их с помощью @Ignore
, как показано в следующем фрагменте кода:
Котлин
@Entity data class User( @PrimaryKey val id: Int, val firstName: String?, val lastName: String?, @Ignore val picture: Bitmap? )
Ява
@Entity public class User { @PrimaryKey public int id; public String firstName; public String lastName; @Ignore Bitmap picture; }
В случаях, когда сущность наследует поля от родительской сущности, обычно проще использовать свойство ignoredColumns
атрибута @Entity
:
Котлин
open class User { var picture: Bitmap? = null } @Entity(ignoredColumns = ["picture"]) data class RemoteUser( @PrimaryKey val id: Int, val hasVpn: Boolean ) : User()
Ява
@Entity(ignoredColumns = "picture") public class RemoteUser extends User { @PrimaryKey public int id; public boolean hasVpn; }
Обеспечить поддержку поиска по таблицам
Room поддерживает несколько типов аннотаций, которые упрощают поиск деталей в таблицах базы данных. Используйте полнотекстовый поиск, если minSdkVersion
вашего приложения не меньше 16.
Поддержка полнотекстового поиска
Если вашему приложению требуется очень быстрый доступ к информации базы данных посредством полнотекстового поиска (FTS), подкрепите свои сущности виртуальной таблицей, которая использует модуль расширения SQLite FTS3 или FTS4. Чтобы использовать эту возможность, доступную в Room 2.1.0 и выше, добавьте аннотацию @Fts3
или @Fts4
к заданному объекту, как показано в следующем фрагменте кода:
Котлин
// 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? )
Ява
// 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
, чтобы указать столбец, в котором хранится информация о языке для каждой строки:
Котлин
@Fts4(languageId = "lid") @Entity(tableName = "users") data class User( // ... @ColumnInfo(name = "lid") val languageId: Int )
Ява
@Fts4(languageId = "lid") @Entity(tableName = "users") public class User { // ... @ColumnInfo(name = "lid") int languageId; }
Room предоставляет несколько других вариантов определения сущностей, поддерживаемых FTS, включая порядок результатов, типы токенизаторов и таблицы, управляемые как внешний контент. Дополнительные сведения об этих параметрах см. в справочнике FtsOptions
.
Индексировать определенные столбцы
Если ваше приложение должно поддерживать версии SDK, которые не поддерживают объекты на базе таблиц FTS3 или FTS4, вы все равно можете индексировать определенные столбцы в базе данных, чтобы ускорить выполнение запросов. Чтобы добавить индексы к сущности, включите свойство indices
в аннотацию @Entity
, в которой перечислены имена столбцов, которые вы хотите включить в индекс или составной индекс. Следующий фрагмент кода демонстрирует этот процесс аннотации:
Котлин
@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? )
Ява
@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; }
Иногда определенные поля или группы полей в базе данных должны быть уникальными. Вы можете обеспечить соблюдение этого свойства уникальности, установив unique
свойства аннотации @Index
значение true
. Следующий пример кода предотвращает наличие в таблице двух строк, содержащих одинаковый набор значений для столбцов firstName
и lastName
:
Котлин
@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? )
Ява
@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 и более поздних версиях вы можете использовать классы неизменяемых значений на основе Java, которые вы аннотируете с помощью @AutoValue
, в качестве сущностей в базе данных вашего приложения. Эта поддержка особенно полезна, когда два экземпляра сущности считаются равными, если их столбцы содержат одинаковые значения.
При использовании классов, аннотированных @AutoValue
, в качестве сущностей, вы можете аннотировать абстрактные методы класса, используя @PrimaryKey
, @ColumnInfo
, @Embedded
и @Relation
. Однако при использовании этих аннотаций необходимо каждый раз включать аннотацию @CopyAnnotations
, чтобы Room мог правильно интерпретировать автоматически созданные реализации методов.
В следующем фрагменте кода показан пример класса, помеченного @AutoValue
, который Room распознает как сущность:
@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); } }