Flutter异步SQLite数据库管理插件drift_sqlite_async的使用
Flutter异步SQLite数据库管理插件drift_sqlite_async的使用
drift_sqlite_async
是一个允许在sqlite_async数据库上使用Drift的Flutter插件。它使得两种API可以在同一应用程序中无缝协作。以下是该插件的主要功能和用法。
功能支持
- 查询操作:包括select、insert、update、delete在内的所有SQL查询。
- 事务处理:支持事务及其嵌套。
- 表更新同步:sqlite_async与Drift之间的表更新会相互传播,无论使用哪种API,查询监控都能正常工作。
- 并发执行:选择查询可以与写入和其他选择语句并行运行。
- 迁移支持(可选):支持Drift的数据库结构迁移。
使用方法
创建数据库连接
要将sqlite_async的SqliteDatabase转换为Drift可用的DatabaseConnection或QueryExecutor,请使用SqliteAsyncDriftConnection
:
@DriftDatabase(tables: [TodoItems])
class AppDatabase extends _$AppDatabase {
AppDatabase(SqliteConnection db) : super(SqliteAsyncDriftConnection(db));
@override
int get schemaVersion => 1;
}
Future<void> main() async {
// sqlite_async数据库实例
final db = SqliteDatabase(path: 'example.db');
// Drift数据库实例
final appdb = AppDatabase(db);
}
完整示例代码
下面是一个完整的示例,演示了如何创建表格、插入数据、监听变化以及关闭数据库连接。
import 'package:drift/drift.dart';
import 'package:drift_sqlite_async/drift_sqlite_async.dart';
import 'package:sqlite_async/sqlite_async.dart';
part 'main.g.dart';
// 定义表格结构
class TodoItems extends Table {
@override
String get tableName => 'todos';
IntColumn get id => integer().autoIncrement()();
TextColumn get description => text()();
}
// 定义数据库类
@DriftDatabase(tables: [TodoItems])
class AppDatabase extends _$AppDatabase {
AppDatabase(SqliteConnection db) : super(SqliteAsyncDriftConnection(db));
@override
int get schemaVersion => 1;
}
Future<void> main() async {
// 初始化sqlite_async数据库
final db = SqliteDatabase(path: 'example.db');
// 手动管理schema
await db.execute(
'CREATE TABLE IF NOT EXISTS todos(id INTEGER PRIMARY KEY, description TEXT)');
// 初始化Drift数据库
final appdb = AppDatabase(db);
// 监听todo列表的变化
appdb.select(appdb.todoItems).watch().listen((todos) {
print('Todos: $todos');
});
// 使用Drift插入数据
await appdb.into(appdb.todoItems).insert(
TodoItemsCompanion.insert(description: 'Test Drift'),
);
// 使用sqlite_async直接插入数据
await db.execute('INSERT INTO todos(description) VALUES(?)', ['Test Direct']);
// 等待一段时间以确保监听器捕获到变化
await Future.delayed(const Duration(milliseconds: 100));
// 关闭数据库连接
await appdb.close();
await db.close();
}
事务与并发
sqlite_async
默认使用WAL模式,并允许多个读取连接,这在与Drift一起使用时同样适用。- Drift的事务使用
sqlite_async
的writeTransaction
,共享相同的锁机制来防止冲突。 - 当前不支持只读事务。
- 支持嵌套事务,通过SAVEPOINT实现。
- Drift的选择语句使用sqlite_async中的读操作(
getAll()
), 并且可以与写入和其他选择语句并行执行。
更新通知
sqlite_async
使用SQLite的update_hook
来检测更改,自动拾取由Drift做出的任何修改。这意味着即使是在Drift中执行的自定义查询也会触发更新事件。此外,从sqlite_async
来的更新也会被传播到Drift,只要没有活跃的写入事务。需要注意的是,在某些情况下可能会出现重复事件,但这通常不会对大多数应用产生重大影响。
Web支持
Web端的支持目前处于Beta阶段,需要Sqlite3 WASM和web worker JavaScript文件。这些文件应该放在项目的web/
目录下。具体步骤请参考官方文档或GitHub上的发布页面获取最新的编译好的worker文件和WASM资源。
以上就是关于drift_sqlite_async
插件的基本介绍及使用方法。如果你有更多问题或者遇到困难,欢迎继续提问!
更多关于Flutter异步SQLite数据库管理插件drift_sqlite_async的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter异步SQLite数据库管理插件drift_sqlite_async的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用drift_sqlite_async
插件进行异步SQLite数据库管理的代码示例。drift_sqlite_async
是一个强大的Flutter插件,它允许你在Flutter应用中以异步方式管理SQLite数据库。
首先,你需要在你的pubspec.yaml
文件中添加drift_sqlite_async
依赖:
dependencies:
flutter:
sdk: flutter
drift: ^x.y.z # 确保使用最新版本
drift_sqlite_async: ^x.y.z # 确保使用最新版本
替换^x.y.z
为实际的最新版本号。
接下来,你需要定义你的数据库模式。这里是一个简单的示例,包含一个用户表:
// lib/data/database.dart
import 'package:drift/drift.dart';
part 'database.g.dart';
@DriftData(tables: [Users])
class MyDatabase extends _$MyDatabase {}
class Users extends Table {
IntColumn get id => integer().autoIncrement().primaryKey()();
TextColumn get name => text().withDefault('Unknown')();
TextColumn get email => text().nullable()();
}
运行flutter pub get
和flutter pub run build_runner build
来生成数据库代码。
然后,你可以创建一个数据库服务类来管理数据库操作:
// lib/data/database_service.dart
import 'package:drift/drift.dart';
import 'package:drift_sqlite_async/drift_sqlite_async.dart';
import 'database.dart';
class DatabaseService {
late final MyDatabase _db;
DatabaseService() {
// 初始化数据库连接
final database = NativeDatabase.memory(); // 使用内存数据库,也可以传入文件路径
_db = MyDatabase(database);
_db.createAllTables(); // 创建所有表
}
// 异步插入用户
Future<void> insertUser(String name, String? email) async {
final user = Users.insert(
name: name,
email: email,
);
await _db.withTransaction((transaction) async {
await transaction.insert(user);
});
}
// 异步查询所有用户
Future<List<UsersRow>> getAllUsers() async {
return await _db.query(Users).getAll();
}
}
UsersRow
是drift
自动生成的,对应于Users
表的行对象。
最后,在你的Flutter应用中使用这个服务:
// lib/main.dart
import 'package:flutter/material.dart';
import 'data/database_service.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final DatabaseService databaseService = DatabaseService();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Drift SQLite Async Example')),
body: FutureBuilder<List<UsersRow>>(
future: databaseService.getAllUsers(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error!}'));
} else {
final users = snapshot.data ?? [];
return ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
final user = users[index];
return ListTile(
title: Text('${user.name} (${user.email ?? 'No Email'})'),
);
},
);
}
},
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await databaseService.insertUser('New User', 'newuser@example.com');
// 重新获取用户列表以显示新插入的用户
setState(() {}); // 注意:这里需要在一个StatefulWidget中使用
},
tooltip: 'Add User',
child: Icon(Icons.add),
),
),
);
}
}
注意:上面的setState
调用在一个StatelessWidget
中是不允许的。为了简化示例,我直接在MyApp
中使用了它。在实际应用中,你应该将数据库逻辑和UI状态管理放在一个StatefulWidget
中。
这个示例展示了如何使用drift_sqlite_async
插件在Flutter中进行异步SQLite数据库管理,包括定义数据库模式、插入数据和查询数据。希望这对你有所帮助!