Google codelab room android

Содержание
  1. Room: Хранение данных на Android для всех и каждого
  2. Использование Room
  3. Преимущества использования Room
  4. Самое большое ограничение в Room: взаимосвязи
  5. Стоит ли использовать Room?
  6. Русские Блоги
  7. Android Room Официальное руководство
  8. Краткое введение
  9. Библиотека импорта
  10. Используйте Room для сохранения локальных данных в базе данных
  11. Определение данных с использованием сущностей Room
  12. Использовать первичный ключ
  13. Аннотация аннотации и уникальность
  14. Определить отношения между объектами
  15. Создать вложенные объекты
  16. Доступ к данным с помощью комнатных DAO
  17. Определить метод запроса
  18. Вставить
  19. обновление
  20. Удалить
  21. Информационный запрос
  22. Простой запрос
  23. Передача параметров в запрос
  24. Возвращает подмножество столбцов
  25. Передача набора параметров
  26. Наблюдаемый запрос
  27. RXJava Реактивный запрос
  28. Прямой доступ к курсору
  29. Многостоловый запрос
  30. Миграция базы данных комнат
  31. Тестовая миграция
  32. Экспортные схемы
  33. Тестовая база данных
  34. Тест Android устройства
  35. Хост тест
  36. Справочный комплекс данных с комнатой
  37. Использование преобразователей типов
  38. Понять, почему Room не допускает ссылки на объекты

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 Официальное руководство

Официальный перевод документов

Краткое введение

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

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

Библиотека импорта

Используйте Room для сохранения локальных данных в базе данных

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

Читайте также:  Андроид читает во всех расширений

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

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

В номере 3 основных компонента:

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

Использовать@DatabaseАннотированные классы должны удовлетворять следующим условиям:

Это наследствоRoomDatabaseАбстрактный класс.

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

  • Содержит абстрактный метод с 0 параметрами и возвращает его с@DaoАннотированный класс.
  • Во время выполнения вы можете позвонитьRoom.databaseBuilder()илиRoom.inMemoryDatabaseBuilder()Получить экземпляр базы данных.

    Entity: Представляет таблицу в базе данных.

    DAO: Содержит методы для доступа к базе данных.

    Эти компоненты и их связь с остальной частью приложения показаны на рисунке 1:

    Рисунок 1. Схема архитектуры помещения

    Следующий фрагмент кода иллюстрирует конфигурацию базы данных с сущностью и DAO:

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

    Примечание: перед созданием экземпляраAppDatabaseОбъекты, вы должны следовать шаблону проектирования Singleton, потому что каждыйRoomdatabaseЭкземпляры довольно дороги, и вам редко требуется доступ к нескольким экземплярам.

    Чтобы испытать номер, попробуйтеAndroid Room with a ViewиПостоянство Android codelabs. Чтобы просмотреть примеры кода комнаты, см.Android Architecture Components samples。

    Определение данных с использованием сущностей Room

    По умолчанию Room создает столбец для каждого поля, определенного в объекте. Если у сущности есть поля, которые вы не хотите сохранять, вы можете использовать@IgnoreЧтобы комментировать их. Должен пройти через класс базы данныхentitiesМассив ссылается на класс сущности.

    Следующий фрагмент кода показывает, как определить сущность:

    Чтобы сохранить поле, Комната должна иметь шанс войти в него. Вы можете выставить поле или предоставить метод получения и установки для него. Если вы используете методы получения и установки, имейте в виду, что они основаны на соглашениях JavaBeans в Room.

    Примечание: сущности могут иметь пустые конструкторы (если соответствующиеDAOКласс может обращаться к каждому постоянному полю) или к конструктору, параметры которого содержат тип и имя, соответствующие полям в сущности. Комната может также использовать весь конструктор или его часть, например конструктор, который получает только некоторые поля.

    Использовать первичный ключ

    Каждый объект должен определить как минимум 1 поле в качестве первичного ключа. Даже если есть только 1 поле, вам все равно нужно использовать@PrimaryKeyАннотации полей. Кроме того, если вы хотите, чтобы Room автоматически назначал идентификаторы сущностям, вы можете установить @ PrimaryKey’sautoGenerateНедвижимость. Если у объекта есть составной первичный ключ, вы можете использовать@EntityАннотированное свойство primaryKeys показано в следующем фрагменте кода:

    By default, Room uses the class name as the database table name. If you want the table to have a different name, set the tableName property of the @Entity annotation, as shown in the following code snippet:
    По умолчанию Room использует имя класса в качестве имени таблицы базы данных. Если вы хотите, чтобы таблица имела другое имя, установите аннотацию @EntitytableNameАтрибуты, как показано в следующем фрагменте кода:

    Обратите внимание: Имена таблиц в SQLite не чувствительны к регистру.

    Подобно свойству tableName, Room использует имя поля в качестве имени столбца в базе данных. Если вы хотите, чтобы столбцы имели разные имена, измените@ColumnInfoВ поле добавляется аннотация, как показано в следующем фрагменте кода:

    Аннотация аннотации и уникальность

    В зависимости от способа доступа к данным вам может потребоваться проиндексировать определенные поля в базе данных, чтобы ускорить запросы. Добавить к сущностииндексПожалуйста@EntityКомментарий содержит атрибут индекса, в котором перечислены имена столбцов, которые должны быть включены в индекс или составной индекс. Следующий фрагмент кода демонстрирует этот процесс аннотации:

    Иногда определенные поля или группы полей в базе данных должны бытьуникальныйA. Может быть изменено@IndexУникальный атрибут аннотации имеет значение true, чтобы применить этот уникальный атрибут. В следующем примере кода запрещается, чтобы таблица содержала две строки, содержащие одинаковый набор значений для столбцов firstName и lastName:

    Определить отношения между объектами

    Поскольку SQLite — это реляционная база данных, вы можете указать отношения между объектами. Хотя большинство библиотек объектно-реляционного отображения позволяют объектным объектам ссылаться друг на друга, Room явно запрещает это. Чтобы понять техническое обоснование этого решения, пожалуйста, поймитеПочему Room не допускает ссылки на объекты。

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

    Например, если есть другая сущность с именем Book, вы можете использовать@ForeignKey Аннотации определяют их отношение к пользовательским объектам, как показано в следующем фрагменте кода:

    Внешние ключи очень мощные, потому что они позволяют вам указать, что происходит при обновлении ссылочной сущности. Например, если вы включите в аннотацию @ForeignKeyonDelete = CASCADE, Вы можете указать SQLite удалить все книги для пользователя, если удаляется соответствующий экземпляр пользователя.

    Обратите внимание: Обработка SQLite@Insert( onconflict=REPLACE)Как набор операций REMOVE и REPLACE вместо одной операции обновления. Этот метод замены конфликтующих значений может повлиять на ограничения внешнего ключа. Для более подробной информации, пожалуйста, смотритеДокументация по SQLiteУсловия использования ON_CONFLICT.

    Создать вложенные объекты

    Иногда, даже если объект содержит несколько полей, вы хотите представить сущность или простой Java-объект (POJO) как единое целое в логике базы данных. В этих случаях вы можете использовать@EmbeddedАннотации для представления объектов, которые должны быть разбиты на подполя в таблице. Встроенные поля могут быть запрошены, как и любой другой столбец.

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

    Таблица, представляющая объект пользователя, содержит столбцы со следующими именами: id, firstName, улица, штат, город и почтовый индекс.

    Обратите внимание: Встроенные поля могут также включать другие встроенные поля.

    Если у сущности есть несколько встроенных полей одного типа, это можно сделать, установивprefixАтрибуты для сохранения каждого столбца уникальным. Предоставленное значение затем добавляется в начало каждого имени столбца во встроенном объекте.

    Доступ к данным с помощью комнатных DAO

    Для доступа к данным вашего приложения используйте «Библиотеку постоянства помещения». Вы можете использовать объекты доступа к данным или DAO. Этот набор объектов DAO составляет основной компонент Помещения, поскольку каждый DAO содержит абстрактные методы для доступа к базе данных приложения.

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

    Читайте также:  Смешные рингтоны для андроид

    Обратите внимание: Перед добавлением класса DAO в приложение,Добавлена ​​библиотека компонентов архитектурыПерейдите в build.gradle приложения.

    DAO может быть интерфейсом или абстрактным классом. Если это абстрактный класс, он может иметь конструктор, который помещаетRoomDatabaseКак единственный параметр. Room создает каждую реализацию DAO во время компиляции.

    Обратите внимание: Если не вызвано на строителяallowMainThreadQueries()В противном случае Room не поддерживает доступ к базе данных в главном потоке, поскольку он может заблокировать пользовательский интерфейс на длительное время. Вернуться кLiveDataилиFlowableАсинхронные запросы для экземпляров исключаются из этого правила, поскольку при необходимости они выполняют запросы в фоновом потоке.

    Определить метод запроса

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

    Вставить

    Когда вы создаете метод DAO и используете@InsertПри аннотировании Room генерирует реализацию, которая вставляет все параметры в базу данных за одну транзакцию.

    Следующий фрагмент кода показывает несколько примеров запросов:

    Если метод @Insert получает только 1 параметр, он может вернуть значение Long, которое является новым rowId вставленного элемента. Если аргумент является массивом или коллекцией, он должен возвращать значение типа long [] или List.

    Для получения дополнительной информации см. Справочную документацию, аннотированную @Insert, иSQLite documentation for rowid tables。

    обновление

    UpdateМетоды используются в базе данных для изменения полей набора сущностей. Он использует первичный ключ каждой сущности для соответствия запросу.

    Следующий фрагмент кода показывает, как определить этот метод:

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

    Удалить

    DeleteЭтот метод используется для удаления серии объектов с заданным параметром из базы данных и использует первичный ключ для сопоставления с соответствующей строкой в ​​базе данных.

    Следующий фрагмент кода показывает, как определить этот метод:

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

    Информационный запрос

    @QueryОсновная аннотация, используемая в классе DAO. Это позволяет выполнять операции чтения / записи в базе данных. Каждый метод @Query проверяется во время компиляции, поэтому, если возникает проблема с запросом, вместо сбоя во время выполнения возникает ошибка компиляции.

    Room также проверяет возвращаемое значение запроса, чтобы, если имена полей в возвращаемом объекте не совпадали с именами соответствующих столбцов в ответе на запрос, Room напомнит вам одним из двух способов:

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

    Если имя поля не совпадает, возникает ошибка.

    Простой запрос

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

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

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

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

    Вы также можете передать несколько параметров или ссылаться на них несколько раз в запросе, как показано в следующем фрагменте кода:

    Возвращает подмножество столбцов

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

    Пока столбцы результата могут быть сопоставлены с возвращаемыми объектами, вы можете вернуть любой объект на основе Java из вашего запроса. Например, вы можете создать следующий общий объект на основе Java (POJO), чтобы получить имя и фамилию пользователя:

    Теперь вы можете использовать этот POJO в вашем методе запроса:

    Room знает, что запрос возвращает значения для столбцов first_name и last_name, и эти значения можно сопоставить с полями в классе NameTuple. Поэтому Room может генерировать соответствующий код. Если запрос возвращает слишком много столбцов или один столбец не существует в классе NameTuple, в Room отобразится предупреждение.

    Примечание: эти POJO также могут быть использованы@EmbeddedПримечания.

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

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

    Наблюдаемый запрос

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

    Обратите вниманиеВ версии 1 Room решает, обновлять ли экземпляр LiveData на основе списка запросов.

    RXJava Реактивный запрос

    Room также может возвращать RXJava2 из заданных вами запросовPublisherиFlowableДвижущийся объект. Чтобы использовать эту функцию, добавьте библиотеку android.arch.persistence.room:rxjava2 в зависимости gradle. Затем вы можете вернуть объект типа, определенный в RXJava2, как показано в следующем фрагменте кода:

    Для получения дополнительной информации см. Google Developers.Комната и RXJavaСтатья.

    Прямой доступ к курсору

    Если логика вашего приложения требует прямого доступа к возвращенным строкам, вы можете вернуть объект Cursor из запроса, как показано в следующем фрагменте кода:

    Обратите вниманиеИспользование API-интерфейса Cursor очень разочаровывает, поскольку не может гарантировать, существует ли строка или какие значения содержит строка. Используйте эту функцию, только если у вас уже есть код, который ожидает Cursor, и код нелегко реорганизовать.

    Многостоловый запрос

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

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

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

    Миграция базы данных комнат

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

    “Room persistence library«Библиотеки позволяют писатьMigrationКласс для хранения пользовательских данных. Каждый класс миграции определяет начальную и конечную версию. Во время выполнения Room запускает каждый класс миграции.migrate()Метод, используя правильный порядок для переноса базы данных в более позднюю версию.

    Читайте также:  Синхронизацию аккаунтов с устройством андроид

    Обратите внимание: Если вы не предоставите необходимую миграцию, Room перестроит базу данных, что означает, что вы потеряете все данные в базе данных.

    Обратите внимание: Чтобы логика миграции работала, используйте полные запросы вместо ссылок на константы, представляющие запросы.

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

    Тестовая миграция

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

    Экспортные схемы

    После компиляции Room экспортирует информацию о схемах базы данных в файл JSON. Чтобы экспортировать схему, установите свойство процессора аннотаций room.schemaLocation в файле build.gradle, как показано в следующем фрагменте кода:

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

    Чтобы проверить эти миграции, добавьте зависимость Maven android.arch.persistence.room:testing и добавьте схему в папку ресурсов, как показано в следующем фрагменте кода:

    Тестовый пакет предоставляет класс MigrationTestHelper, который может читать эти файлы схемы. Он также реализует интерфейс JUnit4 TestRule, поэтому он может управлять созданной базой данных.

    Пример теста миграции приведен в следующем фрагменте:

    Тестовая база данных

    При использовании библиотеки Room для создания базы данных важно проверить стабильность базы данных приложения и пользовательских данных.

    Есть 2 способа проверить базу данных:

    На устройстве Android.

    На машине разработки хоста (не рекомендуется).

    Для конкретной миграции базы данных, см.Миграционный тест。

    Обратите внимание: При запуске тестов для вашего приложения Room позволяет создавать фиктивные экземпляры класса DAO. Таким образом, вам не нужно создавать полную базу данных без тестирования самой базы данных. Эта функция возможна, потому что ваши DAO не будут пропускать какие-либо детали базы данных.

    Тест Android устройства

    Рекомендуемый способ проверки реализации базы данных — написать тест JUnit, работающий на устройстве Android. Поскольку эти тесты не должны создавать действия, они должны выполняться быстрее, чем тесты пользовательского интерфейса.

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

    Хост тест

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

    Обратите внимание: Несмотря на то, что этот параметр позволяет выполнять ваши тесты быстро, это не рекомендуется, поскольку версия SQLite, работающая на вашем устройстве, и пользовательское устройство могут не соответствовать версии на хосте.

    Справочный комплекс данных с комнатой

    Room обеспечивает возможность преобразования между примитивным и коробочным типами, но не допускает ссылки на объекты между сущностями. Этот документ объясняет, как использовать преобразователи типов и почему Room не поддерживает ссылки на объекты.

    Использование преобразователей типов

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

    Например, если мы хотим сохранитьDateПримеры, вы можете написать следующееTypeConverterЧтобы сохранить эквивалентную метку времени UNIX в базе данных:

    В предыдущем примере определены две функции, одна из которых преобразует объект Date в объект Long, а другая выполняет обратное преобразование из Long в Date. Поскольку Room уже знает, как сохранять объекты Long, он может использовать этот конвертер для хранения значений типа Date.

    Затем добавьте в класс AppDatabase@TypeConvertersКомментарии, поэтому AppDatabase может использовать вас для каждогоentityОпределенные конвертеры и DAO:

    Используя эти конвертеры, вы можете использовать свои пользовательские типы в других запросах так же, как и примитивные типы, как показано в следующем фрагменте кода:

    Вы также можете добавить@TypeConvertersОграничено различными областями, включая отдельные объекты, методы DAO и DAO. Для получения дополнительной информации см.@TypeConvertersАннотированная справочная документация.

    Понять, почему Room не допускает ссылки на объекты

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

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

    Однако на стороне клиента этот тип отложенной загрузки невозможен, поскольку он обычно выполняется в потоке пользовательского интерфейса, а запрос информации на диске в потоке пользовательского интерфейса может вызвать значительные проблемы с производительностью. Поток пользовательского интерфейса обычно имеет около 16 мс для вычисления и отрисовки обновленного макета действия, поэтому даже если запрос занимает всего 5 мсек, у вашего приложения может все еще не хватить времени для отрисовки фреймов, что приводит к значительной визуальной задержке. Если параллельно выполняется одна транзакция или если на устройстве выполняются другие задачи с интенсивным использованием диска, выполнение запроса может занять больше времени. Однако, если вы не используете отложенную загрузку, ваше приложение получит больше данных, чем нужно, что вызовет проблемы с использованием памяти.

    Объектно-реляционное отображение обычно оставляет это решение разработчикам, чтобы они могли делать все, что лучше для их варианта использования приложения. Разработчики часто решают поделиться моделью между приложением и пользовательским интерфейсом. Однако это решение невелико по масштабу, поскольку пользовательский интерфейс меняется со временем, а общая модель создает проблемы, которые разработчики вряд ли могут предсказать и отладить.

    Например, рассмотрим пользовательский интерфейс, который загружает список объектов книги, и у каждой книги есть объект автора. Вы могли бы изначально спроектировать свой запрос для использования отложенной загрузки, чтобы использовать метод getAuthor () для возврата автора. Первый вызов getAuthor () запрашивает базу данных. Через некоторое время вы понимаете, что вам нужно показывать имена авторов в пользовательском интерфейсе приложения. Вы можете легко добавить вызовы метода, как показано в следующем фрагменте кода:

    Однако это, казалось бы, безобидное изменение вызвало запрос таблицы автора в главном потоке.

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

    При использовании Room для одновременного обращения к нескольким объектам вам необходимо создать POJO, содержащий каждый объект, а затем написать запрос, который соединяет соответствующие таблицы (запросы к нескольким таблицам, вы должны сначала найти необходимые данные). Эта хорошо структурированная модель в сочетании с мощными возможностями проверки запросов Room позволяет приложениям потреблять меньше ресурсов при загрузке данных, повышая производительность приложений и удобство работы пользователей.

    Источник

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