Перейти к содержимому

Как подключить room android studio

  • автор:

Как подключить room android studio

Полный текст статьи и исходники программы доступны только зарегистрированным участникам сайта.

Прочитайте внимательно условия! В начале каждой статьи указывается, к какому курсу относится данная статья. Например, если статья из 4 курса, значит нужно заплатить за все курсы по четвёртый включительно.

Стоимость регистрации — символические 355 рублей. После регистрации у вас будет доступ ко второму курсу.

Для регистрации сначала необходимо пополнить ЮMoney 410011383280263 на указанную сумму или QIWI (перевод по никнейму), а затем прислать письмо на адрес [email protected] с указанием, на какой кошелёк вы делали оплату и реквизиты, по которым можно вас определить (не прикрепляйте к письму картинки или файлы, пишите в письме). Учитывайте комиссию при переводах.

По поводу перевода на ЮMoney. Если делать перевод по указанной ссылке, то к сумме нужно прибавить 3% самостоятельно. Если вы знаете, как переводить по номеру кошелька 410011383280263 без указанной ссылки, то по идее ваш банк сам рассчитает комиссию. Эти новые правила стали применяться в октябре 2022, возможно вам придётся доплачивать, когда я увижу точную сумму прихода.

Не присылайте в письме мои номера кошельков — поверьте, я их знаю и без вас.

В ответном письме вы получите учётные данные для чтения статей из закрытой зоны за второй курс.

Доступ к третьему курсу обучения доступен только после оплаты второго курса и составляет 355 руб.

Доступ к четвёртому курсу обучения доступен после оплаты третьего курса и составляет 355 руб. и т.д.

При оплате сразу всех курсов одновременно (2-10) цена составит 3195 руб.

Доступ даётся как минимум на один год. Для тех, кто оплатил третий и другие курсы, сроки доступа увеличиваются.

Также возможен приём на PayPal (только для зарубежных пользователей). Обратите внимание, что в этом случае стоимость одного курса составляет 7$.

На данный момент PayPal не доступен в России.

Webmoney тоже не особо доступен в России, но по запросу можно отправить на Z-кошелёк (7S), если вдруг кому-то удобно из других стран.

Библиотека «Room» для начинающего Android-разработчика

Здравствуй, дорогой читатель. Каждый Android-разработчик сталкивался (или столкнётся во время своей профессиональной карьеры) с задачей, в которой необходимо хранить большое количество изменяемых данных. В данной статье будет разобрана библиотека от Google — Room.

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

Статья предназначена для новичков, не знакомых с данной библиотекой, но, желательно, имеющих базовые знаниях о SQLite, Kotlin Coroutines, Kotlin Flow, MVVM.

Все материалы и исходный код можно найти здесь.

Теоретическая часть

Для хранения каких-либо данных, Android-разработчику предоставлены следующие способы: Files, SharedPreferences, SQLite, Resources/Assets. Но какой способ выбрать? Для ответа на данный вопрос можно воспользоваться алгоритмом, изображенном на рисунке ниже.

Алгоритм выбора правильного способа хранения данных в Android.

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

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

Один из способов для работы с SQLite в Android — это, встроенный в Android SDK, SQL API. Данное API позволяет работать с базой данных, но, по-моему мнению, данная технология далеко не простая, а в некоторых моментах даже сложная. В данной статье мы не будем разбирать данную технологию, а сразу перейдем к библиотеке «Room».

Room — это библиотека, представленная на Google I/O в 2017 году. Данная библиотека работает с базой данный SQLite и выполняет большую часть работы за Вас. Все что необходимо разработчику — это «объяснить» библиотеке как выглядят данные, их структуру и способы взаимодействия с помощью специальных аннотаций:

  • @Database — аннотация для объявления базы данных.
  • @Entity — аннотация для объявления сущности базы данных.
  • @Dao — аннотация для объявления интерфейса, который будет заниматься манипулированием данными базы данных.
  • @PrimaryKey — аннотация для объявления первичного ключа сущности.
  • @ColumnInfo — аннотация для настроек конкретного столбца сущности.
  • @Query — аннотация, которая позволяет выполнить SQL-запрос в методах DAO-интерфейса.
  • @Insert — аннотация, которая позволяет выполнить вставку в таблицу базы данных.
  • @Update — аннотация, которая позволяет выполнить обновление некоторых строк в таблице базы данных.
  • @Delete — аннотация, которая позволяет выполнить удаление некоторых строк в таблице базы данных.
  • @Transaction — аннотация, которая помечает метод в DAO-интерфейсе как транзакция.

Это далеко не все аннотации, которые предоставляет «Room», но являющиеся основными. Более подробно аннотации будут рассмотрены в практическом примере.

Также следует отметить, что существуют специальные Tuple-классы, которые никак не помечаются, но являются важной частью при разработке. Данные классы используются при взаимодействии с базой данных (например, когда нам необходимо получить какую-то часть данных из таблицы, а не все данные сразу). Более подробно Tuple-классы будут рассмотрены в практическом примере.

Практическая часть

В качестве не сложного примера, создадим приложение, которое будет «имитировать» создание и отображение статистических данных какой-то игры (например, судоку). Приложение будет состоять из двух экранов: первый — заполнение и отправка данных в базу; второй — список со всеми данными из базы.

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

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

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

dependencies < . implementation 'androidx.room:room-runtime:2.5.0' // Библиотека "Room" kapt "androidx.room:room-compiler:2.5.0" // Кодогенератор implementation 'androidx.room:room-ktx:2.5.0' // Дополнительно для Kotlin Coroutines, Kotlin Flows >
plugins
android < . defaultConfig < . kapt < arguments > > >

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

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

  • таблица «difficulty_levels», в которой будут хранится все доступные уровни сложности;
  • таблица «results», в которой будут хранится все доступные результаты игры;
  • таблица «statistic», в которой будут хранится все статистические данные.

Схематично база данных будет выглядеть следующим образом:

Схема базы данных.

SQL-скрипт для такой базы данных выглядел бы следующим образом:

CREATE TABLE difficulty_levels( id INTEGER PRIMARY KEY, difficulty_name TEXT ); CREATE TABLE results ( id INTEGER PRIMARY KEY, result_name TEXT ); CREATE TABLE statistic ( id INTEGER PRIMARY KEY, result_id INTEGER, difficult_id INTEGER, mistakes INTEGER, points INTEGER, FOREIGN KEY (result_id) REFERENCES results(id), FOREIGN KEY (difficult_id) REFERENCES difficulty_levels(id) );

Примечание: никогда не храните секретные данные (например, пароли) в открытом виде. Всегда хэшируйте их!

После того, как была разобрана схема базы данных, необходимо перейти к созданию сущностей. Создадим data-class DifficultyLevelsDbEntity , который будет описывать таблицу «difficulty_levels»:

@Entity(tableName = "difficulty_levels") data class DifficultyLevelsDbEntity( @PrimaryKey val id: Long, @ColumnInfo(name = "difficulty_name") val difficultyName: String )

В данном случае мы пометили класс аннотацией @Entity , в которой переопределили свойство tableName — данное свойство задаёт имя таблицы. В случае, если бы свойство не было бы определенно, то таблица назвалась аналогично названию класса, т.е. DifficultyLevelsDbEntity.

Также поля класса были помечены аннотациями @PrimaryKey и @ColumnInfo . Первая аннотация помечает поле класса, как первичный ключ, а вторая задаёт название столбца отличное от названии переменной. У аннотации @ColumnInfo есть и другие свойства, например значение по умолчанию, более подробно про свойства данной аннотации можно узнать здесь.

Аналогично создадим класс ReultsDbEntity :

@Entity(tableName = "results") data class ResultsDbEntity( @PrimaryKey val id: Long, @ColumnInfo(name = "result_name") val resultName: String )

Теперь перейдем к созданию более сложной сущности — StatisticDbEntity :

@Entity( tableName = "statistic", indices = [Index("id")], foreignKeys = [ ForeignKey( entity = ResultsDbEntity::class, parentColumns = ["id"], childColumns = ["result_id"] ), ForeignKey( entity = DifficultyLevelsDbEntity::class, parentColumns = ["id"], childColumns = ["difficult_id"] ) ] ) data class StatisticDbEntity( @PrimaryKey(autoGenerate = true) val id: Long, @ColumnInfo(name = "result_id") val resultId: Long, @ColumnInfo(name = "difficult_id") val difficultId: Long, val mistakes: Long, val points: Long )

Аннотации в свойствах data-class’а очень похожи на те, что были созданы ранее. Единственное отличие — в @PrimaryKey было определено свойство autoGenerate = true. Данное свойство «объясняет» библиотеке, что при вставке нового объекта в таблицу, необходимо сгенерировать индекс самостоятельно. Например, в таблице находится пять элементов, при вставке нового элемента поле id автоматически станет равно шести.

Также в аннотации @Entity было определенно больше свойств. Свойство indices «объясняет» библиотеки по каком полю производить индексацию, в данном случае — id.

Свойство foreignKeys объявляет составные ключи. В данном случае составных ключа два — result_id и difficult_id. В объекте ForeignKey указываются сущность-родитель (entity), столбец-родитель (parentColumns) и столбец-ребенок (childColumns).

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

@Dao interface StatisticDao

Когда сущности были созданы, dao-интерфейс объявлен необходимо создать абстрактный класс AppDatabase , который будет описывать базу данных:

@Database( version = 1, entities = [ DifficultyLevelsDbEntity::class, ResultsDbEntity::class, StatisticDbEntity::class ] ) abstract class AppDatabase : RoomDatabase()

Данный класс помечен аннотацией @Database , в которой необходимо обязательно описать два свойства: entities и version. Первое свойство принимает все сущности, которые были описаны выше, а второе свойство задаёт версию базы данных.

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

В самом классе создан абстрактный метод, который возвращает dao-интерфейс.

Так же создадим tupple-класс StatisticInfoTuple , который будет использоваться при «вытягивании» статистических данных из таблицы. Данный класс очень похож на StatisticDbEntity, но поля, которые хранят результат и уровень сложности, уже имеют тип String, так как там будут хранится значения результата и уровня сложности.

data class StatisticInfoTuple( val id: Long, @ColumnInfo(name = "result_name") val result: String, @ColumnInfo(name = "difficulty_name") val difficult: String, val mistakes: Long, val points: Lon

После всех проделанных действий необходимо перейти к реализации dao-интерфейса. В данном интерфейсе создадим три метода, которые будут вставлять новые статистические данные, удалять данные по уникальному значению (id) и получать список всех данных из таблицы statistic:

 @Insert(entity = StatisticDbEntity::class) fun insertNewStatisticData(statistic: StatisticDbEntity) @Query("SELECT statistic.id, result_name, difficulty_name, mistakes, points FROM statistic\n" + "INNER JOIN results ON statistic.result_id = results.id\n" + "INNER JOIN difficulty_levels ON statistic.difficult_id = difficulty_levels.id;") fun getAllStatisticData(): List @Query("DELETE FROM statistic WHERE fun deleteStatisticDataById(statisticId: Long) 

Метод insertNewStatisticData принимает объект класса StatisticDbEntitty — объект, который необходимо вставить. Также данный метод помечен аннотацией @Insert , в которой определено свойство entity, благодаря которому происходит вставка в нужную таблицу.

Методы getAllStatisticData и deleteStatisticDataById помечены аннотацией @Query , которая принимает строку с SQL-запросом. Именно благодаря данному запросу выполняется получение всех элементов или удаление какого-то конкретного элемента.

И последнее, что необходимо сделать с базой данной — создать ее. Для этого выполним следующее:

object Dependencies < private lateinit var applicationContext: Context fun init(context: Context) < applicationContext = context >private val appDatabase: AppDatabase by lazy < Room.databaseBuilder(applicationContext, AppDatabase::class.java, "database.db") .createFromAsset("room_article.db") .build() >>

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

Так же у билдера вызван метод createFromAssets , данный метод заполняет базу данных приготовленными значениями. Т.е., если необходимо, чтобы при инициализации база данных хранила в себе какие-либо значения (например, уровни сложности и доступные результаты), нужно создать отдельно базу данных с помощью сторонних программ, таких как DB Browser for SQLite, заполнить ее и сохранить ее в папку assets приложения.

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

data class Statistic( val resultId: Long, val difficultId: Long, val mistakes: Long, val points: Long )

Теперь необходимо создать репозиторий, который будет обращаться к dao-интерфейсу и манипулировать данными базы данных:

class StatisticRepository(private val statisticDao: StatisticDao) < suspend fun insertNewStatisticData(statisticDbEntity: StatisticDbEntity) < withContext(Dispatchers.IO) < statisticDao.insertNewStatisticData(statisticDbEntity) >> suspend fun getAllStatisticData(): List  < return withContext(Dispatchers.IO) < return@withContext statisticDao.getAllStatisticData() >> suspend fun removeStatisticDataById(id: Long) < withContext(Dispatchers.IO) < statisticDao.deleteStatisticDataById(id) >> >

В данном репозитории три метода, которые вставляют новые данные, получают всю статистику и удаляют какой-то элемент по идентификатору. Все эти методы являются suspend-функциями, т.к. будут вызываться из корутин. Так же следует изменить Dispatcher (withContext), т.к. обращаться к базе данных из основного потока нельзя.

Все эти методы вызываются в корутинах, запущенных во ViewModel, например вставка нового значения:

fun insertNewStatisticDataInDatabase(mistakes: Long, points: Long) < viewModelScope.launch < val newStatistic = Statistic(currentResult, currentDifficultyLevel, mistakes, points) statisticRepository.insertNewStatisticData(newStatistic.toStatisticDbEntity()) >>

Весь рабочий код Вы можете найти здесь.

Рекомендованные источники

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

  • Google Android Documentation — ссылка.
  • Metanit — Введение в SQLite — ссылка.
  • Android — SQLite (база данных, часть 1) — ссылка.
  • Android — Room (часть 1) — ссылка.

Room | Android Jetpack | Kotlin

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

1. SQLite

SQLite — это база данных с открытым исходным кодом, которая поддерживает стандартные возможности SQL, а именно:

  • Синтаксис.
  • Транзакция.
  • Триггеры.
  • Параметризированные операторы.
  • Агрегатные функции.

Данная БД занимает очень мало места примерно 250 Кбайт.

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

  • Integer — Значение представляет собой целое число со знаком, сохраненное в 1, 2, 3, 4, 6 или 8 байтах в зависимости от величины значения.
  • Real — Значение представляет собой значение с плавающей запятой, которое хранится как 8-байтовое число с плавающей точкой IEEE.
  • Text — Значение представляет собой текстовую строку, хранящуюся с использованием кодировки базы данных (UTF-8, UTF-16BE или UTF-16LE)
  • Blob — Значение представляет собой блок данных, который хранится точно так же, как он был введен.

При использовании SQLite предоставляется доступ к файловой системе, что может проходить значительно медленно, поэтому в качестве решения данной проблемы необходимо выполнять все операции с БД не в главном потоке (ui потоке), а нужно использовать фоновый поток.

Ограничения SQLite по сравнению с MySQL и PostgreSQL:

  • Поддерживаемые типы данных. В SQLite их 4, в то время как в MySQL и PostgreSQL больше 20.
  • SQLite не стоит выбирать если вы собираетесь работать над приложением, доступом к БД в которой будут одновременно пользоваться несколько человек. В данном кейсе например лучше выбрать полнофункциональную РСУБД MySQL.
  • В SQLite имеются недостатки с операциями записи, потому что данная БД позволяет единовременно исполнять лишь одну операцию записи.
  • Отсутствие пользовательского управления, т.е. нет возможности управлять связями в таблицах в соответствии с привилегиями.
  • Отсутствие возможности повышения производительности БД за счёт внутренних настроек

2. Что такое Room?

Компоненты архитектуры Android — это набор библиотек, которые помогают создавать надежные, тестируемые и обслуживаемые приложения. Соответственно Room входит в данные компоненты и позволяет упрощать работу с объектами SQLiteDatabase в приложении, уменьшая объем стандартного кода и проверяя запросы SQL во время компиляции.

Room состоит из 3 основных компонентов:

  1. Entity — объект таблицы БД.
  2. Dao — предоставляет методы, которое приложение может производить над базой данных.
  3. Database — содержит базу данных и служит основной точкой доступа для базового подключения к постоянным данным приложения.

Например некоторые методы, которые есть в DAO:

  • Query — запрос на получение, обновлению и удалению данных по какому либо условию.
  • Insert — добавление объекта в базу данных.
  • Delete — удаляет объекты.
  • Update — обновляет объекты.

Метод Query работает асинхронно, а остальные 3 являются синхронными.

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

3. Особенности и подводные камни

  • При настройке модели данных необходимо помнить, что каждое поле в базе данных должно быть общедоступным или иметь геттер и сеттер в стандартном стиле Java Beans.
  • Если сравнивать Room с другими ORM, то преимуществом будет являться в наличии обработчика аннотаций для выполнения всех манипуляций для сохранения данных.
  • Бросающимся в глаза минусом использования Room является то, что он не будет обрабатывать отношения между Entity автоматически, как другие ORM. Данную проблему можно решить, но это приведёт к ограничению внешнего ключа между объектами и не позволит вызывать отношения «1xM» и «Mx1».
  • DAO имеет возможность наследования, что позволяет не плодить те же самые методы Insert, Update, Delete в каждом классе, т.е. можно создать BaseDao и определить общие методы для таблиц, например метод Insert будет выглядеть так: @Insert
    fun insert (vararg obj: T)
  • Следовательно, важно помнить, что все DAO должны быть либо интерфейсами, либо абстрактными классами, потому что Room генерирует их реализацию во время компиляции, включая методы из базового DAO
  • При запросе из базы данных нужно запрашивать только те поля, которые будут использоваться, потому дополнительные неиспользуемые поля увеличивают объем памяти приложения. Также использование только нужных полей приводит к большей скорости выполнения запросов за счет снижения затрат на ввод-вывод. За сопоставление колонок таблиц и объектов можно не бояться, потому что Room это сделает за нас.
  • При создании Database важно помнить, что нельзя создавать много экземпляров, потому что является очень тяжелым. Это можно сделать с помощью Singleton для данного объекта, либо с помощью Dagger.
  • На практике бывают ситуации, когда нужно сохранить в таблицу базы данных не каждое поле, это решается добавлением аннотации @Ignore для поля.
  • Если из базы данных запрашивается список для отображения, можно обратить внимание на библиотеку Paging Library, которая будет возвращать LivePagedListBuilder. Библиотека поможет автоматически вычислить разницу между элементами списка и обновить ваш пользовательский интерфейс.
  • Каждый DAO должен фильтровать свои запросы и реагировать только на необходимые объекты

4. Практика

В данном разделе будет описано пошаговое руководство по созданию приложения с локальной БД. Начальные данные в БД будут заполняться автоматически при запуске приложения — для такого заполнения будут показаны 2 способа: в коде и из готового файла БД. Также в данном приложении можно будет проводить такие действия над БД как добавление, удаление, так и редактирование записей.

Для реализации приложения будет использован следующий стек технологий:

  • RxJava3 — для выполнения запросов к БД в фоновом потоке.

Android, Room «не пишет» в базу данных

Делаю приложение, основной контент которого находится в SQLite базе. Викторина, в которой предлагается угадать животное. Начал изучать Room. Всё работает, информация сохраняется и извлекается из db в рантайме(вижу через логи и Toast). Но когда я открываю саму db(физически) в браузере (DB Browser), то вижу там пустоту. Ни таблиц, ничего. А должны быть мои записи. Что я хочу сделать: открыть только что установленное приложение, добавить в db несколько записей, закрыть приложение, скачать созданную db с устройства на PC и открыть её в браузере, чтобы увидеть её структуру. Пошагово что сделано и где затык: Рутанул эмулятор. Определил путь создаваемой Room базы через: Timber.d(getDatabasePath(AnimalDatabase.DATABASE_NAME).getPath()); Получил: /data/user/0/com.example.animalslibrary/databases/AnimalDB Удалил приложение. Удалил руками вообще весь пакет com.example.animalslibrary . Устанавливаю приложение. Приложение открыто, ни одной записи не добавлено(запись добавляется руками по кнопке). По указанному выше пути ничего не создалось: введите сюда описание изображения Добавляю запись по кнопке. Создаются файлы с моей базой(?) и ещё чем — то непонятным: введите сюда описание изображения Продолжаю добавлять записи кнопкой. Моя база AnimalBD не меняет размера, зато третий файл жиреет с ошеломительной скоростью(скрин после добавления пяти записей): введите сюда описание изображения Закрываю приложение. Скачиваю AnimalBD , открываю — пустота, чистый лист. Даже таблиц нет. Запускаю приложение ещё раз. Пробую достать запись из базы — достаётся. Что я делаю не так вообще? Реально ли достать базу? И если нет, то что мне делать если я хочу чтобы у пользователя уже была заполненная база на момент первого запуска приложения? Не буду же я кодом добавлять уйму строк. В комментариях посоветовали подменять создаваемую Room базу на свою при первом запуске — но для этого мне ведь нужно понять как устроено то что Room создаёт, чтобы создать аналог. Код. Не уверен что он тут вообще нужен, т.к всё работает. Но пусть будет. Не кидайтесь камнями за перегруженную архитектуру, познаю MVC. Activity

 HomeModel homeModel = new HomeModel(Room.databaseBuilder(this, AnimalDatabase.class, AnimalDatabase.DATABASE_NAME) .allowMainThreadQueries() .build()); HomePresenter presenter = new HomePresenter(homeModel); presenter.attachView(this); findViewById(R.id.add_animal_button).setOnClickListener(v -> presenter.buttonClicked()); findViewById(R.id.show_animal_button).setOnClickListener(v -> presenter.button1Clicked()); Timber.d(getDatabasePath(AnimalDatabase.DATABASE_NAME).getPath()); 

HomePresenter

public class HomePresenter < private HomeActivity view; private HomeModel model; public HomePresenter(HomeModel homeModel) < this.model = homeModel; >public void attachView(HomeActivity activity) < this.view = activity; >public void detachView() < this.view = null; >public void viewIsReady() < >public void buttonClicked() < model.addAnimal(); Toast.makeText(view,"ADDED",Toast.LENGTH_LONG).show(); >public void button1Clicked()

HomeModel

public class HomeModel < private AnimalDatabase animalDB; public HomeModel(AnimalDatabase animalDB) < this.animalDB = animalDB; >public void addAnimal() < Animal animal = new Animal(); animal.setName("TIGER"); animalDB.daoAccess().insertAnimal(animal); >public Animal getAnimalById(int id) < return animalDB.daoAccess().getAnimalById(id); >public void initDB()<> > 

DAO

@Dao public interface DAO < @Insert void insertAnimal(Animal animal); @Insert void insertAnimals(ListanimalList); @Query("SELECT*FROM animals WHERE animal_id =:animalId") Animal getAnimalById(int animalId); @Update void updateAnimal(Animal animal); @Delete void deleteAnimal(Animal animal); 

> AnimalDatabase

@Database(entities = , version = 1) @TypeConverters(Converters.class) public abstract class AnimalDatabase extends RoomDatabase

Animal

@Entity(tableName = "animals") public class Animal implements Serializable < @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "animal_id") private int animalId; @ColumnInfo(name = "animal_type") private int type; @ColumnInfo(name = "animal_name") private String name; @ColumnInfo(name = "animal_hints") private String hints; @ColumnInfo(name = "animal_opened_hints") private int hintsOpened; @ColumnInfo(name = "animal_hints_total") private int hintsTotal; @ColumnInfo(name = "animal_pack_id") private int packId; @ColumnInfo(name = "animal_answer_image") private String answerImagePath; public Animal() < >//Тьма геттеров и сеттеров //+ пустой конструктор //+ конструктор, содержащий все поля > 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *