Drift (ранее Moor) — это мощная SQL база данных для Flutter с reactive streams, миграциями и type-safe запросами. Версия 2.0 принесла значительные улучшения.
Что такое Drift?
Drift — это реактивная persistence библиотека для Flutter/Dart.
Преимущества:
— Полная поддержка SQL
— Типобезопасные запросы
— Reactive streams из коробки
— Миграции схемы
— Web поддержка
— Отличная документация
Установка
dependencies:
drift: ^2.0.0
sqlite3_flutter_libs: ^2.0.0
path_provider: ^2.0.0
path: ^1.8.0
dev_dependencies:
drift_dev: ^2.0.0
build_runner: ^2.4.0
Создаём базу данных
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
part 'database.g.dart';
class Users extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get name => text()();
TextColumn get email => text()();
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
}
class AppDatabase extends _$AppDatabase {
AppDatabase(QueryExecutor e) : super(e);
}
// Открываем базу
Future<AppDatabase> openDb() async {
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'db.sqlite'));
return AppDatabase(NativeDatabase.createInBackground(file));
}
Запросы
Простые запросы
// Получить всех пользователей
final allUsers = await select(users).get();
// Найти по ID
final user = await (select(users)..where((u) => u.id.equals(1))).getSingle();
// Фильтрация
final activeUsers = await (select(users)
..where((u) => u.name.contains('John'))
..limit(10)
).get();
Вставка данных
// Вставить одного пользователя
await into(users).insert(UsersCompanion.insert(
name: 'John',
email: 'john@example.com',
));
// Вставить несколько
await batch((batch) {
batch.insertAll(users, [
UsersCompanion.insert(name: 'Alice', email: 'alice@example.com'),
UsersCompanion.insert(name: 'Bob', email: 'bob@example.com'),
]);
});
Обновление
await (update(users)..where((u) => u.id.equals(1)))
.write(UsersCompanion(name: Value('Jane')));
Удаление
await (delete(users)..where((u) => u.id.equals(1))).go();
Reactive streams
// Слушать изменения
final userStream = db.select(users).watch();
userStream.listen((users) {
print('Users updated: ${users.length}');
});
// В виджете
class UserListWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final usersAsync = ref.watch(usersStreamProvider);
return usersAsync.when(
data: (users) => ListView.builder(...),
loading: () => CircularProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
);
}
}
Миграции
// Версия 1
class Users extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get name => text()();
}
// Версия 2
class Users extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get name => text()();
TextColumn get email => text()(); // Новое поле
}
// Migration
migrationBuilder V1ToV2(Migration m) async {
await m.addColumn(users, users.email);
}
Заключение
Drift 2.0 — это лучшая SQL база данных для Flutter. Используйте её для локального хранения, кеширования и offline-first приложений.