Используем join в SQLite-запросах Room для android

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Совсем недавно вышла 2.4.0-alpha04 -версия Room, которая упрощают написание методов DAO и позволяет возвращать данные запросов в формате Map<key,value>. В этом посте мы вспомним про форматы JOIN в SQLite и напишем простой пример, демонстрирующий новую фичу в Room.

Типы Join в SQLite

Для начала, давайте вспомним, что такое join. Join - это возможность объединения двух и более таблиц в одну при помощи команды SELECT и ключевого слова JOIN.

Принцип работы запросов на объединения таблиц в SQL и реляционных базах данных заключается в том, что на основе переданного условия, которое называют предикатом объединения СУБД определяет какие строки из двух таблиц ей нужно объединять.

Вообще, стандарт SQL выделяет гораздо больше модификаторов JOIN:

  1. INNER JOIN – внутреннее объединение таблиц.

  2. LEFT JOIN или LEFT OUTER JOIN – левое внешнее объединение таблиц.

  3. RIGHT JOIN или RIGHT OUTER JOIN – правое внешнее объединение таблиц.

  4. FULL JOIN – полное объединение таблиц.

  5. CROSS JOIN – перекрестное объединение таблиц.

Но в базах данных SQLite (а соответственно в Room) есть только три вида объединения таблиц.

Давайте рассмотрим первый тип объедения. Например, у нас есть приложения для учёта недвижимости. Соответственно у нас есть 2 сущности: пользователь и квартира:

Таким образом, у нас отношение 1 ко многим, то есть 1 владелец и много квартир.

Чтобы сделать запрос к такой БД, состоящей из таких таблиц, можно попробовать

  • Использовать аннотацию @Relation

  • Использовать inner join

    Первый вариант мог бы выглядеть так. Сначала указываем data класс для получения результата:

data class UserWithApartment(
    @Embedded
    val user: User,
    @Relation(
        parentColumn = "userId",
        entityColumn = "ownerId"
    )
    val apartments: List<Apartment>
)

Затем в DAO описываем метод получения данных:

    @Transaction
    @Query("SELECT * FROM User")
    fun getUsersWithAparts():List<UserWithApartment>

Room автоматически, используя аннотацию @Relationвернёт нужные данные.

Однако, теперь нам необязательно создавать дополнительный класс-холдер для получения результата. Такой результат мы можем получить, используя inner join.

Перепишем приведенный пример выше, используя join:

    @Query("SELECT * FROM User JOIN Apartment ON User.userId = Apartment.ownerId")
    fun getUserAndAparts(): Map<User,List<Apartment>>

Таким образом мы получили всех владельцев и список квартир. Таким образом мы избежали лишнего классаа-холдера - однако теперь SQL-запрос стал сложнее. В данном примере мы делаем join на основе первичного ключа пользователя.

На этом всё, надеюсь этот пример был для вас полезен и вы вспомнили что такое join и как его использовать. Не забудьте присоединиться к нам в Telegram, а на платформе AndroidSchool.ru публикуются полезные материалы для Android-разработчика и современные туториалы.

Источник: https://habr.com/ru/post/570400/


Интересные статьи

Интересные статьи

Если вы являетесь регулярным читателем Хабра, то должно быть заметили что за последние несколько лет вышло немало статей о сборе персональных данных с мобильных устройств...
Первая часть Пример на Github В этой статье расскажу о том, как решал проблемы, с которыми столкнулся в предыдущей части при реализации проекта. Во-первых, при анализе трансформируемого...
Приступая к животрепещущей теме резервного копирования на «Битрикс», прежде всего хотелось бы поблагодарить разработчиков, реализовавших автоматическое резервное копирование в облачное хранилище в вер...
Среди многообразия инструментов, анонсированных на Android Dev Summit, особое внимание хочется уделить механизму обновления приложения In-App Updates (IAUs), который помогает разработчикам ус...
Автокэширование в 1с-Битрикс — хорошо развитая и довольно сложная система, позволяющая в разы уменьшить число обращений к базе данных и ускорить выполнение страниц.