Что такое room android
Что такое room android
Полный текст статьи и исходники программы доступны только зарегистрированным участникам сайта.
Прочитайте внимательно условия! В начале каждой статьи указывается, к какому курсу относится данная статья. Например, если статья из 4 курса, значит нужно заплатить за все курсы по четвёртый включительно.
Для регистрации сначала необходимо пополнить ЮMoney(бывший Яндекс.Кошелек) 410011383280263 на указанную сумму (или Webmoney-кошелек P894989790291 (старый R390884954122) или QIWI (перевод по никнейму), а затем прислать письмо на адрес alexander.klimoff@gmail.com с указанием, на какой кошелёк вы делали оплату и реквизиты, по которым можно вас определить (не прикрепляйте к письму картинки или файлы). Учитывайте комиссию при переводах.
В ответном письме вы получите учётные данные для чтения статей из закрытой зоны за второй курс.
Доступ к третьему курсу обучения доступен только после оплаты второго курса и составляет 350 руб.
Доступ к четвёртому курсу обучения доступен после оплаты третьего курса и составляет 350 руб. и т.д.
При оплате сразу всех курсов одновременно (2-9) цена составит 2800 руб.
Доступ даётся как минимум на один год. Для тех, кто оплатил третий и другие курсы, сроки доступа увеличиваются.
Также возможен приём на PayPal (только для зарубежных пользователей). Обратите внимание, что в этом случае стоимость одного курса составляет 7$.
Для котов и зарегистрированных пользователей
9-й курс/Закрытая зона
Очень трудно искать в тёмной комнате чёрную кошку. Особенно, если там её нет.
Работа с базой данных SQLite в Android не отличалась удобством, приходилось писать много строчек кода, прежде чем приступить непосредственно к программированию своей логики. Сторонние разработчики раньше предлагали собственные варианты для уменьшения рутинной работы программиста. Наиболее популярными стали такие библиотеки как Realm, ORMLite, GreenDao, DBFlow, Sugar ORM.
Подключим зависимости. Обязательными являются только первые две зависимости для рантайм-библиотеки и аннотаций. Необходимость плагина kapt (выделены жирным) под вопросом. Плагин уже объявили устаревшим и, возможно, в будущем его не придётся подключать, но пока без kapt не заработало.
Вы вошли на сайт, как гость.
Необходимо зарегистрироваться, чтобы прочитать статью
Полный список
Библиотека Room предоставляет нам удобную обертку для работы с базой данных SQLite. В этом уроке рассмотрим основы. Как подключить к проекту. Как получать, вставлять, обновлять и удалять данные.
Полный список уроков курса:
Подключение к проекту
В build.gradle файл проекта добавьте репозитарий google()
В build.gradle файле модуля добавьте dependencies:
Если у вас студия ниже 3.0 и старые версии Gradle и Android Plugin, то подключение будет выглядеть так:
При работе с Room нам необходимо будет писать SQL запросы. Если вы не знакомы с ними, то имеет смысл прочесть хотя бы основы.
Entity
Аннотацией Entity нам необходимо пометить объект, который мы хотим хранить в базе данных. Для этого создаем класс Employee, который будет представлять собой данные сотрудника: id, имя, зарплата:
Класс помечается аннотацией Entity. Объекты класса Employee будут использоваться при работе с базой данных. Например, мы будем получать их от базы при запросах данных и отправлять их в базу при вставке данных.
Этот же класс Employee будет использован для создания таблицы в базе. В качестве имени таблицы будет использовано имя класса. А поля таблицы будут созданы в соответствии с полями класса.
Аннотацией PrimaryKey мы помечаем поле, которое будет ключом в таблице.
В следующих уроках мы рассмотрим возможности Entity более подробно.
В объекте Dao мы будем описывать методы для работы с базой данных. Нам нужны будут методы для получения списка сотрудников и для добавления/изменения/удаления сотрудников.
Описываем их в интерфейсе с аннотацией Dao.
Методы getAll и getById позволяют получить полный список сотрудников или конкретного сотрудника по id. В аннотации Query нам необходимо прописать соответствующие SQL-запросы, которые будут использованы для получения данных.
Обратите внимание, что в качестве имени таблицы мы используем employee. Напомню, что имя таблицы равно имени Entity класса, т.е. Employee, но в SQLite не важен регистр в именах таблиц, поэтому можем писать employee.
В следующих уроках мы рассмотрим возможности Dao и его аннотаций более подробно.
Database
Аннотацией Database помечаем основной класс по работе с базой данных. Этот класс должен быть абстрактным и наследовать RoomDatabase.
В параметрах аннотации Database указываем, какие Entity будут использоваться, и версию базы. Для каждого Entity класса из списка entities будет создана таблица.
В Database классе необходимо описать абстрактные методы для получения Dao объектов, которые вам понадобятся.
Практика
Все необходимые для работы объекты созданы. Давайте посмотрим, как использовать их для работы с базой данных.
Используем 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
Описываем Entity объект
Теперь Dao для работы с Car объектом
Будем считать, что нам надо только читать все записи, добавлять новые и удалять старые.
В Database необходимо добавить Car в список entities и новый метод для получения CarDao
Т.к. мы добавили новую таблицу, изменилась структура базы данных. И нам необходимо поднять версию базы данных до 2. Но об этом мы подробно поговорим в Уроке 12. А пока можно оставить версию равной 1, удалить старую версию приложения и поставить новую.
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 для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
7 полезных советов для тех, кто использует Room
Room — это уровень абстракции поверх SQLite, который упрощает организацию хранения данных. Если вы ещё мало знакомы с Room, то посмотрите эту вводную статью:
А в этой статье я хотел бы поделиться несколькими советами о том, как максимально эффективно использовать Room.
1. Предварительное заполнение базы данных
Вам нужно добавить данные по умолчанию в вашу базу данных сразу после её создания или в момент первого обращения к ней? Используйте RoomDatabase#Callback. Вызовите метод addCallback при создании вашей базы данных и переопределите либо onCreate, либо onOpen.
onCreate будет вызываться при первом создании базы данных, сразу после создания таблиц. onOpen вызывается при открытии базы данных. Поскольку доступ к DAO возможен только после завершения этих методов, мы создаём новый поток, в котором получаем ссылку на базу данных, затем получаем DAO и вставляем необходимые данные.
Смотрите полный пример здесь.
Примечание: если вы будете использовать подход с ioThread и приложение даст сбой при первом запуске, между созданием базы данных и вставкой, данные никогда не будут вставлены.
2. Использование возможностей наследования DAO
3. Выполнение запросов в транзакциях без шаблонного кода
Аннотирование метода с помощью @Transaction гарантирует, что все операции базы данных, которые вы выполняете в этом методе, будут выполняться внутри одной транзакции. Транзакция не будет выполнена, если в теле метода возникнет исключение.
4. Чтение только того, что вам нужно
Когда вы делаете запрос к базе данных, используете ли вы все поля, которые получаете в ответе? Позаботьтесь об объёме памяти, используемой вашим приложением, и загрузите только те поля, которые вы в конечном итоге будете использовать. Это также увеличит скорость ваших запросов за счёт снижения затрат на ввод-вывод. Room сделает сопоставление между столбцами и объектом за вас.
Рассмотрим этот сложный объект User :
5. Контроль зависимостей между сущностями с внешними ключами
Даже несмотря на то, что Room напрямую не поддерживает связи между сущностями, он позволяет вам определять зависимости между объектами с помощью внешних ключей.
В Room есть аннотация @ForeignKey, которая является частью аннотации @Entity. По функциональности она аналогична внешним ключам в SQLite. Она гарантирует сохранение связей между сущностями при изменениях в базе данных. Чтобы добавить её, определите объект, на который необходимо ссылаться, а также столбцы в текущем объекте и том, на который ссылаетесь.
6. Упрощение запросов один-ко-многим с помощью @Relation
Чтобы сделать это вручную, нам понадобятся 2 запроса: один для получения списка всех пользователей и другой для получения списка домашних животных на основе идентификатора пользователя.
В DAO мы определяем один запрос, а Room будет запрашивать таблицы Users и Pets и самостоятельно сопоставлять объекты.
7. Избежание ложных уведомлений observable-запросов
Допустим, вы хотите получить пользователя по его идентификатору с помощью observable-запроса:
Вы будете получать новый объект User каждый раз, когда он будет обновляться. Но вы также получите этот объект, когда в таблице Users произойдут другие изменения (удаления, обновления или вставки), которые не имеют никакого отношения к интересующему вас пользователю, что приведёт к ложным уведомлениям. Более того, если ваш запрос включает в себя несколько таблиц, вы будете получать новые сообщения всякий раз, когда что-то поменяется в любой из них.
Вот что происходит за кулисами:
Вы должны убедиться, что ваш DAO фильтрует запросы и реагирует только на необходимые объекты.
Полный пример кода смотрите здесь.
Примечание: если вы запрашиваете список для отображения, обратите внимание на библиотеку Paging Library, которая будет возвращать LivePagedListBuilder. Библиотека поможет автоматически вычислить разницу между элементами списка и обновить ваш пользовательский интерфейс.
Room: Один ко многим
Один ко многим
Тут все просто: в документации сказано как организовать классы, чтобы получить связь сущностей «один ко многим». Берем 2 сущности:
и связываем их в единую сущность:
Для получения новой сущности типа DialogWithTags нужно использовать Dao, которое будет загружать данные из таблицы DialogPojo, при этом автоматически загрузятся tags из связанной таблицы (entity = TagPojo.class):
Используя эти знания уже можно собирать звезду смерти приложение. Однако, в процессе работы могут возникнуть вопросы, ответы на которые лучше знать на подготовительных этапах.
Целостность
Как это ни странно, но запрос на получение DialogWithTags не гарантирует целостность данных. Т.е., возможна ситуация, когда DialogPojo уже загружен, а список TagPojo нет. Предупреждение о возможных проблемах появляется на этапе компиляции программы.А кто их читает, эти предупреждения? Для обеспечения целостности данных, в запрос нужно добавить аннотацию Transaction.
Сохранение
К сожалению, сохранить модель DialogWithTags просто так не получится. Сохранять данные нужно отдельно и, желательно, в одной транзакции, например:
Live Data
Самое большое разочарование ждет при использовании LiveData. Данные будут живыми только для Embedded поля dialog. Изменения для tags отслеживаться не будут. Конечно можно объявить поле tags как LiveData, но, не стоит забывать, что LiveData вернет данные только в том случае, если зарегистрирован хотя бы один обсервер.
Урок 5. Room. Основы
Библиотека Room предоставляет нам удобную обертку для работы с базой данных SQLite. В этом уроке рассмотрим основы. Как подключить к проекту. Как получать, вставлять, обновлять и удалять данные.
Полный список уроков курса:
Подключение к проекту
В build.gradle файл проекта добавьте репозитарий google()
В build.gradle файле модуля добавьте dependencies:
Если у вас студия ниже 3.0 и старые версии Gradle и Android Plugin, то подключение будет выглядеть так:
При работе с Room нам необходимо будет писать SQL запросы. Если вы не знакомы с ними, то имеет смысл прочесть хотя бы основы.
Entity
Аннотацией Entity нам необходимо пометить объект, который мы хотим хранить в базе данных. Для этого создаем класс Employee, который будет представлять собой данные сотрудника: id, имя, зарплата:
Класс помечается аннотацией Entity. Объекты класса Employee будут использоваться при работе с базой данных. Например, мы будем получать их от базы при запросах данных и отправлять их в базу при вставке данных.
Этот же класс Employee будет использован для создания таблицы в базе. В качестве имени таблицы будет использовано имя класса. А поля таблицы будут созданы в соответствии с полями класса.
Аннотацией PrimaryKey мы помечаем поле, которое будет ключом в таблице.
В следующих уроках мы рассмотрим возможности Entity более подробно.
В объекте Dao мы будем описывать методы для работы с базой данных. Нам нужны будут методы для получения списка сотрудников и для добавления/изменения/удаления сотрудников.
Описываем их в интерфейсе с аннотацией Dao.
Методы getAll и getById позволяют получить полный список сотрудников или конкретного сотрудника по id. В аннотации Query нам необходимо прописать соответствующие SQL-запросы, которые будут использованы для получения данных.
Обратите внимание, что в качестве имени таблицы мы используем employee. Напомню, что имя таблицы равно имени Entity класса, т.е. Employee, но в SQLite не важен регистр в именах таблиц, поэтому можем писать employee.
В следующих уроках мы рассмотрим возможности Dao и его аннотаций более подробно.
Database
Аннотацией Database помечаем основной класс по работе с базой данных. Этот класс должен быть абстрактным и наследовать RoomDatabase.
В параметрах аннотации Database указываем, какие Entity будут использоваться, и версию базы. Для каждого Entity класса из списка entities будет создана таблица.
В Database классе необходимо описать абстрактные методы для получения Dao объектов, которые вам понадобятся.
Практика
Все необходимые для работы объекты созданы. Давайте посмотрим, как использовать их для работы с базой данных.
Используем 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
Описываем Entity объект
Теперь Dao для работы с Car объектом
Будем считать, что нам надо только читать все записи, добавлять новые и удалять старые.
В Database необходимо добавить Car в список entities и новый метод для получения CarDao
Т.к. мы добавили новую таблицу, изменилась структура базы данных. И нам необходимо поднять версию базы данных до 2. Но об этом мы подробно поговорим в Уроке 12. А пока можно оставить версию равной 1, удалить старую версию приложения и поставить новую.
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 для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме