Room
Room - обертка над SQLIte/Realm/DAO, представленная на Goolge I/O. Room provides an abstraction layer over SQLite in a similar way to Retrofit with network requests. Пример использования: androidx.room. https://habr.com/ru/post/336196/ https://developer.android.com/training/data-storage/room/accessing-data
Выглядит как достаточно безопасная штука, которая переводит объекты сразу в базу и обратно. Если делать все по инструкции, ошибиться невозможно (про sqli) Подробно: https://medium.com/@appmattus/android-security-sql-injection-with-the-room-persistence-library-69f4e286960f
Две норм статьи по разработке с помощью Room: https://medium.com/androiddevelopers/7-steps-to-room-27a5fe5f99b2 https://medium.com/androiddevelopers/7-pro-tips-for-room-fbadea4bfbd1
С точки зрения разработки
Поэтапное создание https://codelabs.developers.google.com/codelabs/android-room-with-a-view-kotlin/#4
Подключение в проект
В build.gradle файл проекта добавьте репозитарий google()
В build.gradle файле модуля добавьте dependencies:
Структура
Три основных компонента - Entity
, Dao
, Database
Entity
- объект, который хотим хранить в базе. Используется для создания таблицы. Database
- Dao
- описывает методы для работы с базой данных.
Entity
По умолчанию, имя создаваемой таблицы будет название класса. Следующим образом задается свое название таблицы:
Переопределить имя поля:
По умолчанию Room
определяет тип данных для поля в таблице по типу данных поля в Entity
классе. Но мы можем явно указать свой тип.
У PrimaryKey
есть параметр autoGenerate
. Он позволяет включить для поля режим autoincrement
, в котором база данных сама будет генерировать значение, если вы его не укажете.
Чтобы создать составной ключ, используйте параметр primaryKeys.
Внешний ключ (ForeignKeys
) Внешние ключи позволяют связывать таблицы между собой. Если вы еще не знакомы с ними, то можете почитать о них в инете. В выше рассмотренных примерах у нас есть класс Employee
для хранения данных по сотрудникам. Давайте создадим класс Car
для хранения данных по машинам. И каждая машина должна быть прикреплена к какому-либо сотруднику.
Важно: When we use foreign key dont forget to put onDelete = ForeignKey.CASCADE
this way if you delete an data it will also delete de dependency. This way you won't have false data or data that are never use
Индекс (Index) Индексы могут повысить производительность вашей таблицы. Если вы еще не знакомы с ними, то можете почитать о них в инете. В аннотации Entity
есть параметр indicies
, который позволяет задавать индексы.
Создаем два индекса: один по полю salary
, а другой по двум полям first_name
и last_name
.
Индекс для одного поля также может быть настроен через параметр index
аннотации ColumnInfo
Будет создан индекс для поле salary
.
Вложенные объекты Пусть у нас есть класс Address
, с данными о адресе. Это обычный класс, не Entity
.
И мы хотим использовать его в Entity классе Employee
Простое решение - использовать аннотацию Embedded. Если у вас получается так, что совпадают имена каких-то полей в основном объекте и в Embedded объекте, то используйте префикс для Embedded объекта.
В этом случае к именам полей Embedded объекта в таблице будет добавлен указанный префикс.
Ignore Аннотация Ignore позволяет подсказать Room, что это поле не должно записываться в базу или читаться из нее.
Dao
Обратите внимание, что в качестве имени таблицы мы используем employee
. Напомню, что имя таблицы равно имени Entity
класса, т.е. Employee
, но в SQLite
не важен регистр в именах таблиц, поэтому можем писать employee
. Для вставки/обновления/удаления используются методы insert/update/delete
с соответствующими аннотациями. Тут никакие запросы указывать не нужно. Названия методов могут быть любыми. Главное - аннотации.
Database
Аннотацией Database
помечаем основной класс по работе с базой данных. Этот класс должен быть абстрактным и наследовать RoomDatabase
.
В параметрах аннотации Database
указываем, какие Entity
будут использоваться, и версию базы. Для каждого Entity
класса из списка entities
будет создана таблица.
В Database
классе необходимо описать абстрактные методы для получения Dao
объектов, которые вам понадобятся.
Как пользоваться
Database
объект - это стартовая точка. Его создание выглядит так:
Используем Application Context
, а также указываем AppDatabase
класс и имя файла для базы.
Учитывайте, что при вызове этого кода Room
каждый раз будет создавать новый экземпляр AppDatabase
. Эти экземпляры очень тяжелые и рекомендуется использовать один экземпляр для всех ваших операций. Поэтому вам необходимо позаботиться о синглтоне для этого объекта. Это можно сделать с помощью Dagger
, например.
Если вы не используете Dagger
(или другой DI механизм), то можно использовать Application
класс для создания и хранения AppDatabase
:
Не забудьте добавить App
класс в манифест
В коде получение базы будет выглядеть так:
Из Database объекта получаем Dao.
Теперь мы можем работать с Employee
объектами. Но эти операции должны выполняться не в UI
потоке. Иначе мы получим Exception
.
Добавление нового сотрудника в базу будет выглядеть так:
Метод getAll вернет нам всех сотрудников в List
Получение сотрудника по id:
UI поток
Операции по работе с базой данных - синхронные, и должны выполняться не в UI
потоке.
В случае с Query
операциями мы можем сделать их асинхронными используя LiveData
или RxJava
.
Last updated
Was this helpful?