Exposed с SQLite на Android? / Хабр

На данный момент, на Android есть несколько основных способов использовать базы данных:

Так уж вышло, что я фуллстэк, да еще и очень люблю котлиновскую мультиплатформу. И всё это время я был готов мириться с тем, что всякие хранения данных на JS/Web — это крайне увлекательное развлечение (нет, не увлекательное), но вот тот факт, что для JVM на серверах и для JVM на Android нужно писать разный код для баз данных, который по-сути своей делает одну и ту же работу — меня не устраивало. И так вышло, что на одном из проектов меня это допекло и я таки подключил Exposed с SQLite в проект.

Джентльменский набор

Пожалуй, начать следует с важных ссылок:

  • Exposed как виновник торжества

  • Проект этого туториала

  • Xerial SQLite JDBC

Также в проекте используется фича градла VERSION_CATALOGS для централизованного управления зависимостями из файла gradle/libs.versions.toml

Само приложение будет очень простым — мы будем иметь один экран с одним полем ввода и возможностью записать данные из этого поля в базу/прочитать оттуда. Я даже позволю себе кощунство и не буду разбивать это дело на кучу модулей, кусков условного MVVM и прочего такого, уж простите 🙂

Поехали

Итак, в проекте туториала есть два модуля:

  • lib

  • app

Как нетрудно догадаться, lib — это некоторая мультиплатформенная библиотека, app — наше миниприложение. В lib у нас подключены две платформы: JVM и Android. Для андроида я указал AndroidManifest с единственной строчкой-пакетом и код для инициализации базы данных, а в JVM положил нашу таблицу.

Начнем препарировать

Итак, код инициализации базы:

fun Context.initDatabase(): Database {
    return Database.connect(
        // "jdbc:sqlite:/data/data/app.text/database.db"
        "jdbc:${SQLiteDialect.dialectName}:/data/data/${packageName}/database.db"
    )
}

В качестве ресивера мы принимаем Context — это нужно, чтобы получить впоследствие packageName и использовать его для указания местоположения базы данных. Вообще, кусок строки /data/data/${packageName}/database.db может быть произвольным (лишь бы приложение имело доступ к указанному месту), но рекомендуется именно /data/data/${packageName}/, поскольку это папка приложения и вне просторов рутованных устройств к этой папке ничто кроме приложения и системы доступа не имеет.

Сам адрес базы ничем не отличается от обычного адреса, как и способ подключения.

Теперь, таблица. Для простоты я положу её условное описание, поскольку иначе это будет ~50 строк кода:

class DataTable : Table("data") {
  fun put(text: String)
  fun get(): String
}

Итак, это обычная Exposed таблица с функцией вставки и получения. В целом, ничего особо интересного.

То, ради чего мы все здесь собрались

Самое вкусное и важное лежит в папке jniLibs. Фактически, это просто копия папки из Xerial SQLite и вся основная магия заключена в этих 4-х файлах .so.

Ну а дальше всё скучно

Открыть, написать, закрыть, открыть. Вот и весь тест

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

Что по-итогу

В двух словах добавление Exposed с SQLite выглядит так:

  • Добавить зависимости (exposed jdbc, xerial sqlite jdbc)

  • Добавить jniLibs, можно в либу, хотя это не всегда хорошая идея

  • (Опционально, если хотите использовать таблицы на JVM) — добавить в gradle dependencies андроид секции пункт dependsOn(jvmMain)

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

platform/external/sqlite — Git в Google

Клонировать этот репозиторий:

Филиалы

  • master
  • android-s-beta-4
  • android-s-beta-5
  • android -s-qpr3-бета -1
  • android-s-v2-beta-3
  • android-s-v2-preview-1
  • android-t-preview-1
  • android10-c2f2-релиз
  • android10-c2f2-s1-релиз
  • android10-c2f2-s2-release
Подробнее. ..

Теги

  • android-13.0.0_r52
  • android-13.0.0_r51
  • android-platform-13.0.0_r8
  • android-13.0.0_r50
  • android-platform-12.1.0_r16
  • android-platform-12.0. 0_r20
  • андроид-платформа-11.0.0_r31
  • android-security-11.0.0_r68
  • android-security-12.0.0_r48
  • android-security-13.0.0_r6
Подробнее…

  1. ed7e0d9 Слияние «Добавить новых владельцев во внешний / sqlite» от Treehugger Робот · 5 недель назад main master
  2. e24d7a5 Добавить новых владельцев во external/sqlite by Lee Shombert · 5 недель назад
  3. 88324e4 Слияние «Исправить переполнение стека в PhoneNumberUtilsTest» am: 524720d226 от Treehugger Robot · 4 месяца назад android-u-beta-1-gpl
  4. 524720d Слияние «Исправить переполнение стека в PhoneNumberUtilsTest» от Treehugger Robot · 4 месяца назад
  5. 149fec4 Исправление переполнения стека в PhoneNumberUtilsTest, автор Colin Cross · 4 месяца назад 10 месяцев назад 16к с телефонами
  6. cec0f89 Слияние «reland: sqlite: Обновление до SQLite 3. 39.2″ am: b75a2f5464 am: dbe4ca3d0d am: 71c4f49e16 by Lalit Maganti · 10 месяцев назад 0,39,2 дюйма: b75a2f5464 am: dbe4ca3d0d Лалит Маганти · 10 месяцев назад
  7. dbe4ca3 Слияние «reland: sqlite: Обновление до SQLite 3.39.2» am: b75a2f5464 Лалит Маганти · 10 месяцев назад
  8. b75a2f5 Слияние «reland: sqlite : обновление до SQLite 3.39. .2» от Lalit Maganti · 10 месяцев назад main-16k
  9. 7a053d1 reland: sqlite: Upgrade to SQLite 3.39.2 by Lalit Maganti · 10 месяцев назад b2f утра: 4870eb1a39 по Henri Chataing · 10 месяцев назад
  10. 4870eb1 Слияние «Revert «sqlite: Upgrade to SQLite 3.39.2″» am: 22a8ee44aa am: 40f9fcea8f am: 0faad96b2f by Henri Chataing · 10 месяцев назад
  11. 0faad96 Merge «Вернуть» sqlite: обновить до SQLite 3.39.2″» утра: 22a8ee44aa утра: 40f9fcea8f от Henri Chataing · 10 месяцев назад
  12. 40f9fce Слияние «Вернуть» sqlite: обновление до SQLite 3.39.2″ am: 22a8ee44aa by Henri Chataing · 10 месяцев назад
  13. 22a8ee4 Слияние «Вернуть» sqlite: обновление до SQLite 3. 3 9.2 «» by Henri Chataing · 10 месяцев назад
  14. ba39973 Revert «sqlite: Upgrade to SQLite 3.39.2» by Henri Chataing · 10 месяцев назад
  15. ea59b37 Merge «sqlite: Upgrade to SQLite 3.39.2» am: bbf3b94355 am: 1d5 d0bae00 am: d3c09d5eca am: 770b1b5b22 by Treehugger Robot · 10 месяцев назад
  16. 770b1b5 Слияние «sqlite: Обновление до SQLite 3.39.2″ am: bbf3b94355 am: 1d5d0bae00 am: d3c09d5eca от Treehugger Robot · 10 месяцев назад .2» утра: bbf3b94355 утра: 1d5d0bae00 by Treehugger Robot · 10 месяцев назад

Android Room или SQLite — что лучше? | Удеан Мбано | DVT Software Engineering

Опубликовано в

·

Чтение: 5 мин.

·

12 апреля 2022 г.

За последние шесть лет работы Android-разработчиком я понял, что наличие онлайн- и офлайн-приложений для хранения данных дает клиентам лучший пользовательский опыт. Причина? Эти приложения работают быстрее и надежнее.

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

Таким образом, возможность сохранять данные на мобильном устройстве и возобновлять съемку позже становится идеальной. Я буду рассматривать устройства Android и их основную базу данных, официально известную как SQLite, которую Ричард Хипп представил 17 августа 2000 года. Однако в 2017 году Google представила сохраняемость Android Room, чтобы преодолеть недостатки SQLite.

Я работаю с SQLite над реальными приложениями уже несколько лет. Одним из приложений, над которым я работал, было приложение для розничной торговли (продажи и мерчандайзинг), которое продается по всей Африке. У него были различные рабочие функции, такие как обзоры продуктов, фотоработы, настраиваемые формы, обзоры запасов и заказы. Эти задания синхронизировались между мобильными устройствами и веб-системами в режиме реального времени или по запросу. Быть автономным и онлайн-приложением было важно в повседневной деятельности торговых представителей. Например, делая много фотографий в районе с плохим подключением к Интернету, можно сделать много фотографий с помощью приложения, а затем загрузить их в веб-систему при наличии хорошего подключения к Интернету.

Веб-система будет использовать бизнес-отчетность, а такая информация, как заказы, будет связана с различными системами ERP, такими как Sage Evolution 200, SAP Business, IQ Retail и т. д.

Существенным недостатком, который мы заметили при использовании SQLite, было обслуживание. Например, изменение базы данных приложения для новых изменений приведет к тому, что команда разработчиков напишет множество запросов с измененными операторами и вручную настроит номер версии. Кроме того, привязка к различным объектам из языков программирования, таких как Java или Kotlin, приведет к шаблонному коду. Мне пришлось написать много кода для выполнения определенных операций с базой данных. Например, при вставке обширного списка информации я бы использовал список массивов с курсором SQLite. Базы данных SQLite были огромными; когда группа поддержки запрашивала журналы приложения, это приводило к тому, что приложение экспортировало большой сжатый файл, который оно отправляло по электронной почте. SQLite сгенерировал большой файл apk, что означало замедление загрузки или установки обновлений приложения Google Play Store.

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

Ниже приведена схема архитектуры базы данных SQLite:

Я работал над другим приложением, которое использовало Android Room, приложением VanSales. Основным языком программирования, используемым для этого приложения для Android, был Kotlin. Продавцы фургонов использовали это приложение на разных складах для погрузки и разгрузки товара. В приложении были такие функции, как мобильная печать, оплата наличными, регистрация, оплата и загрузка счетов. Действия будут происходить в депо или складах, а проверки безопасности и проверки пользователей будут выполняться на контрольно-пропускных пунктах.

Поддерживать и обновлять базу данных было очень удобно, так как Room использует функции ORM (объектно-реляционное сопоставление), что означает, что ваш код должен быть слабо связанным и объектно-ориентированным как разработчик Android, что приводит к меньшему количеству строк кода.

Например, при вставке большого списка информации Android Room предоставляет функции insertAll(List) или updateAll(List), встроенные функции которых позволяют вставлять или обновлять обширный список за несколько секунд, что, как мне показалось, было потрясающим.

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

Room также автоматически обновлял базу данных, когда таблицы обновлялись с помощью класса данных и автоматической миграции. При использовании Auto-Migrations для обновления базы данных будет запускаться только указанный номер версии, что делает его более эффективным. Структура была слабо связанной, и было легко обновлять запросы, поскольку код был структурирован в DAO и репозиториях.

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

При компиляции или при сборке приложения Android Room проверяет пользовательские SQL-запросы, сообщая вам о неправильном синтаксисе и не позволяя создавать apk.

Android Room сгенерировал apk-файл меньшего размера, что ускорило загрузку или установку обновлений приложений из Google Play Store. Для службы поддержки запросы из журналов приложений торговых представителей и отправка их по электронной почте в базу данных для расследований по жалобам или запросам были быстрее. Еще я заметил, что загрузка больших списков на экране телефона происходила быстрее, чем при использовании SQLite. Android Room является мощным и сокращает время загрузки данных.

Структура сборки базы данных была разделена на Entities, DAO и Repositories. Android Room хорошо работает с новыми платформами Android, такими как MVVM, популярными среди разработчиков Android. Модель представления будет отвечать за извлечение информации из базы данных и отправку данных в хранилище с использованием репозитория, который связан с DAO, где вы будете писать запросы к базе данных или объекты.