Источник: Nuances of Programming
Введение
SQLite появилась в 2000 году и с тех пор стала одним из самых популярных решений для встраивания баз данных в локальные приложения. Давайте в демонстрационном проекте создадим очень простое приложение для управления задачами, которое может создавать, обновлять и удалять элементы из базового интерфейса.
Если у вас ещё нет Flutter, скачать можно на странице установки. Исходный код, который мы используем, доступен здесь на GitHub.
Конфигурация проекта
Итак, что нам нужно для использования SQLite в приложении на Flutter? Во-первых, включить пакет sqflite внутри проекта в pubspec.yaml вот таким образом:
Мы указали здесь версию пакета sqflite 1.2.0 или новее и path_provider версии не старше 1.6.0, а проект упростили для лучшего понимания и облегчения работы с ним.
Создаём простую модель
Для хранения данных нам понадобится модель. Простой класс модели данных позволяет применять необходимые методы для преобразования приемлемого для SQLite формата данных в объект, который может быть использован в приложении. Абстрактный класс Model будет служить базовым классом для моделей данных. Этот файл находится в lib/models/model.dart:
Класс Model очень прост и удобен для определения свойств/методов (таких как приведённый выше id), которые можно ожидать от моделей данных. Это позволяет создавать одну или несколько конкретных моделей данных, соответствующих такому базовому шаблону проектирования. В примере с нашим приложением для управления задачами класс модели конкретного элемента создаётся в lib/models/todo-item.dart:
Этот класс TodoItem содержит свойства для task и complete и простой конструктор для создания нового элемента, а для преобразования между экземплярами TodoItem и объектами карты, используемыми базой данных, определены методы toMap и fromMap. Заметим, что id добавляется в карту, только будучи значением не null.
Класс базы данных
Ради удобства и простоты сопровождения основные методы обработки базы данных помещаем в lib/services/db.dart (так лучше, чем разбрасывать логику обработки данных по всему приложению):
Этот класс абстрактный: из него нельзя создавать объекты, да и нужна всего одна его копия в памяти. В свойстве _db у него есть ссылка на базу данных SQLite. Номер версии базы данных захардкоден значением 1, хотя в более сложных приложениях версию базы данных можно использовать для миграции схем базы данных вверх или вниз в версии, благодаря чему можно развёртывать новые функции без необходимости стирать базу данных и начинать всё с нуля.
Внутри метода init создаётся экземпляр базы данных SQLite с именем базы данных example специально для нашего проекта. Если база данных с именем example ещё не существует, автоматически вызывается onCreate. Именно здесь находятся запросы на создание структуры таблицы. В нашем случае создаётся таблица todo_items с первичным ключом для id и полями, которые соответствуют свойствам в классе TodoItem.
Метод query, равно как и методы insert, update и delete, определяется для выполнения стандартных операций в базе данных. Благодаря им, у нас есть простые абстракции и возможность поместить логику обработки данных в этот класс, что может быть очень полезным при рефакторинге и сопровождении кода в приложении. Если бы их не было, нам пришлось бы, например, искать и заменять кучу строк в разных файлах или устранять странные ошибки после внесения простых изменений.
Главный файл приложения
И последнее, но не менее важное: логика приложения и пользовательский интерфейс у нас находятся в lib/main.dart
Это стандартный файл, определяющий внешний вид и поведение любого приложения с Flutter. Во время инициализации строка WidgetsFlutterBinding.ensureInitialized() обеспечит корректную инициализацию приложения Flutter, тогда как база данных инициализируется с помощью await DB.init().
Когда приложение запускается и виджет MyHomePage визуализируется, вызов refresh() извлекает список задач из таблицы todo_items и выполняет его отображение на список List объектов TodoItem. Они отображаются в главном ListView через средство доступа _items, которое принимает список List объектов TodoItem и форматирует его как список виджетов, содержащий текстовый элемент задач и индикатор завершённости этого элемента.
Задачи добавляются нажатием на плавающую круглую кнопку и введением названия задачи. При нажатии на кнопку Save вновь созданный элемент списка задач будет добавлен в базу данных с помощью DB.insert . Нажав на задачу в списке, можно переключаться между состояниями завершена /не завершена: здесь используем булеву переменную complete и сохраняем изменённый объект в базе данных с помощью DB.update. Проведя пальцем по задаче в горизонтальном направлении, можно удалить элемент задач: используем для этого метод DB.delete. Всякий раз, когда в список вносятся изменения, вызов refresh() с последующим setState() обеспечивает правильность обновления списка.
Заключение
SQLite представляет удобный способ локального хранения данных в приложении. В примере проекта было показано, как выполнять основные операции управления данными для создания, добавления, изменения, обновления и удаления простых записей в базе данных SQLite. Ещё больше о плагине sqflite и функциях, которые он поддерживает, можно узнать здесь.
Спасибо за внимание и удачи в вашем следующем проекте на Flutter!
Читайте также:
Читайте нас в телеграмме и vk
Перевод статьи Kenneth Reilly: How to use Flutter with SQLite