Как определять данные с помощью объектов Room

Когда вы используете библиотеку Room Persistence для хранения данных приложения, вы определяете объекты, которые хотите сохранить. Каждой сущности соответствует таблица в связанной базе данных Room, а каждый экземпляр сущности представляет собой строку данных в соответствующей таблице.

Используя объекты Room, вы можете определить схему базы данных без написания кода SQL.

Как устроен объект

Каждый объект Room определяется как класс с аннотацией @Entity. Объект Room содержит свойства для каждого столбца в соответствующей таблице базы данных, в том числе один или несколько столбцов, составляющих первичный ключ.

В следующем примере кода показана сущность, которая определяет таблицу User со столбцами для идентификатора, имени и фамилии:

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

По умолчанию 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
)

Как определить основной ключ

Для каждого объекта Room необходимо определить первичный ключ, чтобы однозначно идентифицировать каждую строку в соответствующей таблице базы данных. Для этого добавьте аннотацию @PrimaryKey к одному столбцу:

@PrimaryKey val id: Int

Как определить составной первичный ключ

Если вам нужно, чтобы экземпляры объекта уникально идентифицировались по комбинации нескольких столбцов, вы можете определить составной первичный ключ, перечислив эти столбцы в свойстве primaryKeys объекта @Entity:

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

Игнорировать свойства

По умолчанию Room создает столбец для каждого свойства, определенного в объекте. Чтобы Room не сохранял свойство, добавьте к нему аннотацию @Ignore:

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

Если объект наследует свойства от родительского объекта, используйте свойство ignoredColumns аннотации @Entity:

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

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

Room поддерживает несколько аннотаций, которые позволяют искать информацию в таблицах базы данных.

поддержка полнотекстового поиска;

Если в вашем приложении требуется быстрый полнотекстовый поиск, создайте для объектов виртуальную таблицу. Используйте расширение FTS3 или FTS4 SQLite или расширение FTS5 SQLite.

Чтобы использовать эту возможность, добавьте аннотацию @Fts3, @Fts4 или @Fts5 к объекту.

// Use `@Fts3` only if your app has strict disk space requirements.
@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 an INTEGER type and column name "rowid".
    @PrimaryKey @ColumnInfo(name = "rowid") val id: Long,
    @ColumnInfo(name = "first_name") val firstName: String
)

Чтобы настроить токенизацию информации из базы данных в таблицах FTS, используйте параметр tokenizer. Room предоставляет несколько встроенных токенизаторов через FtsOptions, в том числе TOKENIZER_SIMPLE, TOKENIZER_PORTER и TOKENIZER_UNICODE61:

@Fts4(tokenizer = FtsOptions.TOKENIZER_UNICODE61)
@Entity(tableName = "users")
data class User(
    @PrimaryKey @ColumnInfo(name = "rowid") val id: Long,
    @ColumnInfo(name = "first_name") val firstName: String
)

Room предоставляет несколько других вариантов определения объектов, поддерживаемых полнотекстовым поиском, включая сортировку результатов, удаление индексов из столбцов и таблицы, управляемые как внешний контент. Подробнее об этих вариантах можно узнать в справочнике по FtsOptions.

Как индексировать определенные столбцы

Если вы используете AndroidSQLiteDriver и вам нужно поддерживать версии SDK, которые не поддерживают объекты, основанные на таблицах FTS3, FTS4 или FTS5, вы все равно можете индексировать определенные столбцы в базе данных, чтобы ускорить выполнение запросов. Если вы используете BundledSQLiteDriver, Room поддерживает все версии FTS независимо от версии Android SDK.

Чтобы добавить индексы к объекту, включите свойство indices в аннотацию @Entity. Укажите названия столбцов, которые нужно включить в индекс или составной индекс. В следующем фрагменте кода показано, как добавить индексы:

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

Иногда определенные столбцы или группы столбцов в базе данных должны содержать уникальные значения. Чтобы обеспечить уникальность, задайте для свойства unique аннотации @Index значение true. В приведенном ниже фрагменте кода показано, как обеспечить уникальность:

@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,
)