Room kotlin android уроки

Урок 5. Room. Основы

Библиотека Room предоставляет нам удобную обертку для работы с базой данных SQLite. В этом уроке рассмотрим основы. Как подключить к проекту. Как получать, вставлять, обновлять и удалять данные.

Полный список уроков курса:

Подключение к проекту

В build.gradle файл проекта добавьте репозитарий google()

В build.gradle файле модуля добавьте dependencies:

Если у вас студия ниже 3.0 и старые версии Gradle и Android Plugin, то подключение будет выглядеть так:

Room имеет три основных компонента: Entity, Dao и Database. Рассмотрим их на небольшом примере, в котором будем создавать базу данных для хранения данных по сотрудникам (англ. — employee).

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

Entity

Аннотацией Entity нам необходимо пометить объект, который мы хотим хранить в базе данных. Для этого создаем класс Employee, который будет представлять собой данные сотрудника: id, имя, зарплата:

Класс помечается аннотацией Entity. Объекты класса Employee будут использоваться при работе с базой данных. Например, мы будем получать их от базы при запросах данных и отправлять их в базу при вставке данных.

Этот же класс Employee будет использован для создания таблицы в базе. В качестве имени таблицы будет использовано имя класса. А поля таблицы будут созданы в соответствии с полями класса.

Аннотацией PrimaryKey мы помечаем поле, которое будет ключом в таблице.

В следующих уроках мы рассмотрим возможности Entity более подробно.

В объекте Dao мы будем описывать методы для работы с базой данных. Нам нужны будут методы для получения списка сотрудников и для добавления/изменения/удаления сотрудников.

Описываем их в интерфейсе с аннотацией Dao.

Методы getAll и getById позволяют получить полный список сотрудников или конкретного сотрудника по id. В аннотации Query нам необходимо прописать соответствующие SQL-запросы, которые будут использованы для получения данных.

Обратите внимание, что в качестве имени таблицы мы используем employee. Напомню, что имя таблицы равно имени Entity класса, т.е. Employee, но в SQLite не важен регистр в именах таблиц, поэтому можем писать employee.

Для вставки/обновления/удаления используются методы insert/update/delete с соответствующими аннотациями. Тут никакие запросы указывать не нужно. Названия методов могут быть любыми. Главное — аннотации.

В следующих уроках мы рассмотрим возможности Dao и его аннотаций более подробно.

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:

Обновление данных по сотруднику.

Room будет искать в таблице запись по ключевому полю, т.е. по id. Если в объекте employee не заполнено поле id, то по умолчанию в нашем примере оно будет равно нулю и Room просто не найдет такого сотрудника (если, конечно, у вас нет записи с >

Аналогично обновлению, Room будет искать запись по ключевому полю, т.е. по id

Давайте для примера добавим еще один тип объекта — Car.

Описываем Entity объект

Теперь Dao для работы с Car объектом

Будем считать, что нам надо только читать все записи, добавлять новые и удалять старые.

Читайте также:  Сбросить настройки до заводских android xiaomi

В Database необходимо добавить Car в список entities и новый метод для получения CarDao

Т.к. мы добавили новую таблицу, изменилась структура базы данных. И нам необходимо поднять версию базы данных до 2. Но об этом мы подробно поговорим в Уроке 12. А пока можно оставить версию равной 1, удалить старую версию приложения и поставить новую.

UI поток

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

В случае с Query операциями мы можем сделать их асинхронными используя LiveData или RxJava. Об этом еще поговорим в следующих уроках.

В случае insert/update/delete вы можете обернуть эти методы в асинхронный RxJava. В моем блоге есть статья на эту тему.

Также, вы можете использовать allowMainThreadQueries в билдере создания AppDatabase

В этом случае вы не будете получать Exception при работе в UI потоке. Но вы должны понимать, что это плохая практика, и может добавить ощутимых тормозов вашему приложению.

Переход на Room

Если вы надумали с SQLite мигрировать на Room, то вот пара полезных ссылок по этой теме:

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

Room: Хранение данных на Android для всех и каждого

Room — это новый способ сохранить данные приложений в Android-приложении, представленный в этом году на Google I/O. Это часть новойAndroid Architecture, группа библиотек от Google, которые поддерживают уместную архитектуру приложений. Room предлагается в качестве альтернативы Realm, ORMLite, GreenDao и многим другим.

Room — это высокоуровневый интерфейс для низкоуровневых привязок SQLite, встроенных в Android, о которых вы можете узнать больше в документации. Он выполняет большую часть своей работы во время компиляции, создавая API-интерфейс поверх встроенного SQLite API, поэтому вам не нужно работать с Cursor или ContentResolver.

Использование Room

Во-первых, добавьте Room в свой проект. После этого вам нужно будет передать в Room, как выглядят ваши данные. Предположим, имеется простой класс модели, который выглядит следующим образом:

Чтобы рассказать Room о классе Person, добавляем аннотицию Entity к классу и @PrimaryKey к ключу:

Благодаря этим двум аннотациям Room теперь знает, как создать таблицу для хранения экземпляров Person.

Важная вещь, которую следует учитывать при настройке ваших моделей: каждое поле, которое хранится в базе данных, должно быть общедоступным или иметь геттер и сеттер в стандартном стиле Java Beans (например, getName () и setName (имя строки)).

В классе Person теперь есть вся информация, которая требуется Room для создания таблиц, но у вас нет способа фактически добавлять, запрашивать или удалять данные из базы данных. Вот почему вам нужно будет сделать объект доступа к данным (DAO). DAO предоставляет интерфейс в самой базе данных и занимается манипулированием хранимыми данными Person.

Вот простой интерфейс DAO для класса Person:

Первое, что нужно заметить, это то, что PersonDaoэто интерфейс, а не класс. Другая интересная деталь — это инструкции SQL в аннотациях Query (). Операторы SQL говорят Room, какую информацию вы хотите получить из базы данных. Они также проверяются во время компиляции. Поэтому, если вы измените подпись метода List getAllPeopleWithFavoriteColor ( название цвета ) на List getAllPeopleWithFavoriteColor ( int color ), Room выдаст ошибку во время компиляции:

И если вы сделаете опечатку в выражении SQL, например, напишите favoriteColors ( множественное число ) вместо favoriteColor ( единственное число ), Room также выдаст ошибку компиляции:

Вы не можете получить экземпляр PersonDao, потому что это интерфейс. Чтобы иметь возможность использовать классы DAO, вам необходимо создать класс базы данных. За кулисами этот класс будет отвечать за ведение самой базы данных и предоставление экземпляров DAO.

Вы можете создать свой класс базы данных всего за пару строк:

Это лишь описание структуры базы данных, но сама база данных будет жить в одном файле. Чтобы получить экземпляр AppDatabase, сохраненный в файле с именем populus-database, вы должны написать:

Если вы хотите получить все данные обо всех Person, которые находятся в базе данных, вы могли бы написать:

Преимущества использования Room

В отличие от большинства ORM, Room использует обработчик аннотации для выполнения всей своей манеры сохранения данных. Это означает, что ни ваши классы приложений, ни классы моделей не должны ничего расширять в Room, в отличие от многих других ORM, включая Realm и SugarORM. Как вы видели при ошибках с аннотациями Query () выше, вы также получаете возможность проверки корректности SQL-запросов во время компиляции, что может сэкономить вам много хлопот.

Room также позволяет вам наблюдать за изменениями данных, интегрируя их как с API LiveData Архитектурных Компонентов, так и с RxJava 2. Это означает, что если у вас сложная схема, где изменения в базе данных должны появляться в нескольких местах вашего приложения, Room делает уведомления об изменениях. Это мощное дополнение может быть включено одной строкой. Все, что вам нужно сделать, это изменить тип возвращаемых значений.

Читайте также:  Обновленные файлы для андроид

Например, этот метод:

Самое большое ограничение в Room: взаимосвязи

Самым большим ограничением в Room является то, что он не будет обрабатывать отношения с другими типами сущностей для вас автоматически, как и другие ORM. Это означает, что если вы хотите отслеживать домашних животных:

То Room выдаст ошибку компиляци, так как не знает, как сохранить отношения между Person и Pet:

Ошибка при компиляции предлагает конвертер типов, который преобразует объекты в примитивы, которые могут быть непосредственно сохранены в SQL. Поскольку List нельзя свести к примитиву, вам нужно сделать что-то другое. Это отношения «один ко многим», где у одного Person может быть много Pet. Room не может моделировать такие отношения, но она может справиться с обратными отношениями — у каждого Pet есть один Person. Чтобы смоделировать это, удалите поле для Pet в Person и добавьте поле ownerId в класс Pet:

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

Чтобы получить всех домашних животных, принадлежащих конкретному человеку, вы можете использовать запрос, который находит всех домашних животных с данным идентификатором владельца. Например, вы можете добавить в свой DAO следующий метод:

Стоит ли использовать Room?

Если вы уже настроили сохранение данных в своем приложении и довольны им, то ничего не изменяйте. Каждая ORM и встроенная реализация SQLite будут продолжать работать так же, как и раньше. Room — это всего лишь еще один вариант сохранения данных.

Если вы используете SQLite или собираетесь использовать его, вы должны попробовать Room. Он обладает всеми возможностями, необходимыми для выполнения расширенных запросов, одновременно устраняя необходимость писать SQL-запросы для поддержки базы данных самостоятельно.

Источник

Русские Блоги

Android Room By Kotlin

Введение в демо

Эта демонстрация представляет собой простое приложение, демонстрирующее использование синтаксиса Room в Kotlin.

Введение в комнату

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

Эта библиотека помогает вам создать локальную базу данных на устройстве, на котором запущено приложение.

1. Создайте пустой проект.

2. Обновите файл Gradle.

Библиотеку компонентов необходимо добавить в файл Gradle
в вашем build.gradle Внесите следующие изменения в (Модуль: приложение):
Примените его, добавив плагин Kotlin для обработки аннотаций kapt к другим плагинам, определенным в верхней части файла (Module: app).
bulid.gradle

В коде dependencies Добавьте следующий код в конец блока.

ПозжеПроект build.gradle (Project)

Здесь вы также можете перейти на официальный сайт, чтобы найти номер последней версииссылка на сайт

3. Создайте объект

Room позволяет создавать таблицы через Entity. Начнем сейчас.

Проанализируйте значение аннотации @ в следующем коде

  • @Entity(tableName = «todo_database»)
    каждый @Entity Класс представляет собой таблицу SQLite. Аннотируйте свой класс, чтобы показать, что это класс сущности. Если вы хотите, чтобы имя таблицы отличалось от имени класса, вы можете указать имя таблицы. Эта таблица называется «todo_database»
  • @PrimaryKey
    Каждой сущности нужен первичный ключ. Используйте здесь autoGenerate = true Для автоматического создания
  • @ColumnInfo(name = «todo_title»)
    Если вы хотите, чтобы имя столбца в таблице отличалось от имени переменной-члена, укажите это имя. Это назовет столбец «todo_title».

4. Создайте Дао

Что такое Дао?

В DAO (объект доступа к данным) укажите запросы SQL и свяжите их с вызовами методов. Компилятор проверяет SQL и генерирует запросы @Insert для общих запросов (например) из удобных комментариев. Room использует DAO для создания чистого API для вашего кода.

DAO должен быть интерфейсом или абстрактным классом.

По умолчанию все запросы должны выполняться в отдельном потоке.

В Room есть поддержка сопрограмм, что позволяет аннотировать ваши запросы с помощью модификатора приостановки, а затем вызывать их из сопрограммы или другой приостановленной функции.

Написать Дао

Давайте напишем DAO, который предоставляет следующий запрос:

  1. Расположите все заголовки в алфавитном порядке
  2. Вставить Todo
  3. Удалить все Todo
  1. TodoDao Интерфейс; Дао должен быть интерфейсом или абстрактным классом.
  2. В @Dao В аннотации указано, что это класс комнаты Дао.
  3. suspend fun insert(todo: Todo) Объявите функцию паузы для вставки Todo.
  4. Аннотация @Insert — это специальная аннотация метода DAO, вам не нужно предоставлять какой-либо SQL! (Существуют также аннотации @Delete и @Update для удаления и обновления строк, но они не используются в этом приложении.)
  5. onConflict = OnConflictStrategy.IGNORE Если Todo, выбранный в политике конфликтов, в точности совпадает с существующим Todo в списке, слово будет проигнорировано.
  6. suspend fun deleteAll() Объявите функцию паузы для удаления всех Todos.
  • на @Query Использование слишком много и разное, пожалуйста, проверьте информацию самостоятельно

5. Класс LiveData

При изменении данных обычно требуются некоторые меры, например отображение обновленных данных в пользовательском интерфейсе. Это означает, что вы должны наблюдать за данными, чтобы вы могли реагировать на их изменение.

Читайте также:  Ворд для андроид с возможностью редактирования

В зависимости от того, как хранятся данные, это может быть сложно. Наблюдение за изменениями данных между несколькими компонентами приложения может создать четкий и строгий путь зависимости между компонентами. Это очень затрудняет тестирование и отладку.

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

Позже в этой демонстрации изменения данных будут отслеживаться через Observer.

7, добавьте RoomDatabase

Что такое RoomDatabase?

  • Комната — это уровень базы данных поверх базы данных SQLite.
  • Room отвечает за выполнение общих задач, которые ранее выполнялись NET.
  • Room использует DAO для отправки запросов к своей базе данных.
  • По умолчанию, чтобы избежать снижения производительности пользовательского интерфейса, Room не позволяет выполнять запросы в основном потоке. Когда запрос Room возвращает LiveData, запрос будет автоматически выполняться асинхронно в фоновом потоке.
  • Room обеспечивает проверку операторов SQLite во время компиляции.

Написать RomDatabase

Класс RoomDatabase должен быть абстрактным и может расширять RoomDatabase. Обычно для всего приложения требуется только один экземпляр базы данных Room.

Давайте сделаем это сейчас. Создайте файл класса Kotlin с именем WordRoomDatabase и добавьте следующий код:

Взглянем на код:

  • Room Класс базы данных должен быть abstract И расширить RoomDatabase
  • Вы используете класс аннотации в качестве базы данных Room, @Database И используйте параметр комментария, чтобы объявить сущность, принадлежащую базе данных, и установить номер версии. Каждой сущности соответствует таблица, которая будет создана в базе данных. Миграция базы данных выходит за рамки этой лаборатории кода, поэтому exportSchema Установить здесь как false Чтобы избежать генерации предупреждений. В реальном приложении вам следует рассмотреть возможность создания каталога для Room для экспорта архитектуры, чтобы текущую архитектуру можно было проверить в системе контроля версий.
  • Вы переходите за каждый @Dao Создайте абстрактный метод «получения», чтобы база данных предоставляла свой DAO.
  • Мы определили singleton , TodoRoomDatabase Чтобы предотвратить одновременное открытие нескольких экземпляров базы данных.
  • getDatabase Вернуться к синглтону. Он будет использовать построитель базы данных Room при первом доступе к базе данных. RoomDatabase Создайте объект в контексте приложения класса TodoRoomDatabase И назовите его для создания базы данных «todo_database».

8. Создать репозиторий

Что такое репозиторий?

Класс репозитория абстрагирует доступ к нескольким источникам данных. Репозиторий не является частью библиотеки архитектурных компонентов, но является рекомендуемым разделением кода и передовыми методами архитектуры. Класс Repository предоставляет чистый API для доступа к данным остальной части приложения.

Написать репозиторий

Создайте файл класса Kotlin с именем TodoRepository И вставьте в него следующий код:

  1. DAO передается конструктору репозитория, а не всей базе данных. Это потому, что ему нужен только доступ к DAO, потому что DAO содержит все методы чтения / записи базы данных. Нет необходимости предоставлять всю базу данных в репозиторий.
  2. Todo Список является государственной собственностью. по LiveData Из Room Получите список слов для инициализации; причина, по которой мы можем это сделать, заключается в том, что мы определили getAlphabetizedTodoList возвращение LiveData Методы. Room Все запросы выполняются в отдельных потоках. Потом, когда LiveData Когда данные изменились, observed Наблюдатель будет уведомлен в основном потоке.
  3. В suspend Модификатор сообщает компилятору, что это нужно вызывать из сопрограммы или другой функции паузы.

9. Создайте ViewModel.

Что такое VIewModel?

ViewModel Роль заключается в предоставлении пользовательского интерфейса данных и сохранении изменений конфигурации. ViewModel Выступает в качестве коммуникационного центра между репозиторием и пользовательским интерфейсом. Вы также можете использовать ViewModel Делитесь данными между клипами. ViewModel Это часть библиотеки жизненного цикла.

Зачем использовать ViewModel

ViewModel Сохраняйте данные пользовательского интерфейса приложения с учетом жизненного цикла, чтобы сохранить изменения конфигурации. Данные пользовательского интерфейса приложения Activity Класс и Fragment Разделите классы, чтобы лучше следовать принципу единой ответственности: ваши действия и фрагменты отвечают за вывод данных на экран, а вы ViewModel Может отвечать за сохранение и обработку всех данных, требуемых пользовательским интерфейсом.
в ViewModel , LiveData Используется для переменных данных, которые будет использовать или отображать пользовательский интерфейс. Использование LiveData дает несколько преимуществ:

  1. Вы можете поставить наблюдателей на данные (вместо опроса на предмет изменений) и только
    Обновляйте пользовательский интерфейс только при фактическом изменении данных.
  2. Библиотека ресурсов и пользовательский интерфейс полностью разделены.
  3. Нет обращений к базе данных от ViewModel (Все это обрабатывается в репозитории), чтобы сделать код более тестируемым.

viewModelScope

В Котлине все сопрограммы запускаются внутри CoroutineScope . Осциллограф контролирует жизненный цикл сопрограммы через ее работу. При отмене операции области консолидации будут отменены все сопрограммы, запущенные в области консолидации.

AndroidX lifecycle-viewmodel-ktx Библиотека добавлена viewModelScope Функция расширения класса ViewModel Чтобы вы могли использовать диапазон.

Реализовать ViewModel

Создайте для этого файл класса Kotlin и добавьте следующий код:

10. Наконец

Теперь нам нужно только вызвать метод вставки во ViewModel для вставки данных.

Конкретный код тестового интерфейса (RecyclerView и т. Д.) Показан по ссылке Github ниже.

Источник

Оцените статью