Определите данные с помощью объектов комнаты

Когда вы используете библиотеку постоянства комнаты для хранения данных вашего приложения, вы определяете сущности, представляющие объекты, которые вы хотите сохранить. Каждая сущность соответствует таблице в связанной базе данных 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 распознает как сущность:

Пользователь.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);
    }
}