Insert list room android

Урок 8. Room. Query

В этом уроке поговорим подробнее про Query. В каком виде мы можем получать данные: List, массив, Cursor, LiveData. Как передавать параметры. Как получать только некоторые поля. Как с помощью Query выполнять update и delete запросы в Room.

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

В качестве примера будем работать с таким Entity классом:

List, массив, Cursor

Чтобы запросить из базы Employee-объекты, необходимо в Dao создать метод с аннотацией Query

В Query прописываем запрос, который должен вернуть данные. А в качестве возвращаемого типа указываем List .

При вызове этого метода, Room сделает запрос в таблицу employee, конвертирует полученные данные в Employee объекты и упакует их в List.

Запрос, который вы указываете в Query проверяется на правильность синтаксиса во время компиляции. Если в нем будет ошибка, система вам сразу подскажет это.

Вместо List, мы также можем использовать массив:

и даже Cursor, если это необходимо по каким-то причинам:

LiveData

Room умеет возвращать данные в LiveData обертке.

Получение данных в коде Activity выглядит так:

Получаем LiveData и подписываемся на него.

Использование LiveData имеет огромное преимущество перед использование списка или массива. Подписавшись на LiveData, вы будете получать свежие данные при их изменении в базе. Т.е. при добавлении новых, удалении старых или обновлении текущих данных в таблице employee, Room снова выполнит ваш Query запрос, и вы получите в onChanged методе актуальные данные с учетом последних изменений. Вам больше не надо самим запрашивать эти данные каждый раз. И все это будет приходить вам в UI поток.

Передача параметров

В Query можно передавать параметры, чтобы сделать запросы более конкретными.

Например, запрос данных по id

Перед параметром employeeId в запросе должно стоять двоеточие. Room возьмет значение этого параметра из метода и подставит его в запрос.

Рассмотрим еще несколько примеров:

Поиск сотрудников с зарплатой больше заданного значения

Поиск сотрудников с зарплатой в заданном диапазоне

Поиск сотрудников по имени или фамилии

Поиск сотрудников по списку id.

Subsets

Часто при запросе данных нам нужно получить из таблицы не все поля, а только некоторые. Такие запросы быстрее и легче, чем тянуть все поля.

Допустим нам надо получать только имя и фамилию сотрудника. Если сделать так:

то уже при компиляции получим ошибку: The columns returned by the query does not have the fields [id,salary] in Employee even though they are annotated as non-null or primitive. Columns returned by the query: [first_name,last_name].

Room сообщает, что в данных, которые вернет этот запрос, не хватает полей, чтобы заполнить все поля объекта Employee.

В этом случае мы можем использовать отдельный объект.

Обратите внимание, что он не Entity. Это обычный класс. С помощью ColumnInfo мы настраиваем имена полей, чтобы они совпадали с полями таблицы.

Используем этот класс в методе запроса:

Теперь все ок, и мы получим список Name объектов.

Вы также можете в этих не Entity классах использовать вложенные классы с аннотацией @Embedded. Подробно об этой аннотации мы говорили в Уроке 6.

insert, update и delete запросы

Аннотации Insert, Update и Delete позволяют нам модифицировать данные, но их возможности слишком ограниченны. Часто возникает необходимость обновить только некоторые поля или удалить записи по определенному условию. Это можно сделать запросами с помощью Query.

Читайте также:  Pdalife android angry birds

Давайте рассмотрим пару примеров.

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

Опционально метод может возвращать int значение, в котором мы получим количество обновленных строк. Если вам это не нужно, то делайте метод void.

Вызов метода будет выглядеть так:

Удаление сотрудников по списку id

Запросы удаления также могут возвращать int значение, в котором мы получим количество удаленных строк.

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

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

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

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

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

Источник

Урок 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 объектов, которые вам понадобятся.

Читайте также:  Videodevil для андроид тв установить

Практика

Все необходимые для работы объекты созданы. Давайте посмотрим, как использовать их для работы с базой данных.

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 объектом

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

В 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 для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

Урок 7. Room. Insert, Update, Delete, Transaction

В этом уроке рассмотрим подробнее аннотации Insert, Update и Delete. А также узнаем, как использовать транзакции в Room.

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

Insert

Аннотация Insert — это простой способ вставить объект в базу данных. Мы уже использовали ее в примерах прошлых уроков.

Читайте также:  Как посмотреть геолокацию айфона с андроида

Использование этой аннотации выглядит так:

В Dao интерфейсе описываем метод, который на вход принимает Entity объект. К методу добавляем аннотацию Insert и Room сгенерирует необходимый код в реализации этого интерфейса.

Давайте посмотрим, какие еще возможности у нас есть.

Вставка нескольких объектов

Мы можем передавать в метод не один, а несколько объектов, используя varargs

Также, это может быть список:

Или это вообще может быть любой Iterable:

При вызове этого метода вы можете использовать массив или коллекцию.

Получение id

При вставке метод Insert может возвращать id только что добавленной записи. Для этого надо описать метод так, чтобы он возвращал long.

Если в Employee есть числовой первичный ключ, то именно его значение вы и получите.

В случае добавления нескольких записей, необходимо использовать long[]

Режимы вставки

Рассмотрим ситуацию, когда мы вставляем в таблицу запись, но обнаруживается, что запись с таким ключом там уже есть. По умолчанию мы получим ошибку: SQLiteConstraintException: UNIQUE constraint failed. И ничего в базу не запишется.

Но это можно поменять с помощью параметра onConflict.

В режиме REPLACE старая запись будет заменена новой. Этот режим хорошо подходит, если вам надо вставить запись, если ее еще нет в таблице или обновить запись, если она уже есть.

Также есть режим IGNORE. В этом режиме будет оставлена старая запись и операция вставки не будет выполнена.

Более подробно об этих режимах можно прочесть здесь.

Update

Эта аннотация аналогична Insert, но она не вставляет, а обновляет объекты в бд.

Так же, как и с Insert мы можем использовать коллекции и varargs, чтобы обновлять несколько объектов сразу.

Update ищет в бд запись по ключу. Если не найдет, то ничего не произойдет. Если найдет, то обновит все поля, а не только те, которые мы заполнили в Entity объекте.

Мы можем получить количество обновленных записей. Для этого опишите метод так, чтобы он возвращал int.

Как и Insert, Update поддерживает параметр onConflict.

Delete

Методы с аннотацией Delete будут удалять объекты.

В Delete методах мы также можем использовать коллекции и varargs, чтобы удалять несколько объектов сразу.

Delete ищет в бд запись по ключу.

Мы можем получить количество удаленных записей. Для этого необходимо описать метод так, чтобы он возвращал int.

Аннотации Insert, Update и Delete позволяют выполнить простые операции. Для более сложных действий необходимо использовать SQL запросы: INSERT, UPDATE и DELETE. Это можно сделать с помощью аннотации Query. В следующем уроке мы рассмотрим эту возможность.

Транзакции

Аннотация @Transaction позволяет выполнять несколько методов в рамках одной транзакции.

Рассмотрим пример, когда нам нужно добавить объекты Car и Employee:

EmployeeCarDao — отдельный Dao объект для работы с комбинацией Car и Employee. В нем описываем методы для вставки объектов по отдельности, а затем оба этих метода вызываем в одном методе с аннотацией Transaction. В итоге вставятся либо оба объекта, либо, в случае возникновения ошибки, ни один из них.

Обратите внимание, что в этом случае Dao — не интерфейс, а абстрактный класс.

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

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

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

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

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

Источник

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