Flutter数据库管理插件drift的使用
Flutter数据库管理插件drift的使用
Drift简介
Drift 是一个为Flutter和Dart构建的反应式持久化库,它建立在SQLite之上。Drift具有以下特点:
- Flexible(灵活):Drift允许你在SQL和Dart中编写查询,提供两种语言的流利API。你可以过滤和排序结果或使用联接来对多个表进行查询。甚至可以使用复杂的SQL特性如
WITH
和WINDOW
子句。 - Feature rich(功能丰富):内置支持事务、模式迁移、复杂过滤器和表达式、批量更新和联接。我们甚至有一个内置的SQL IDE!
- Modular(模块化):通过内置对DAO和SQL文件中的
import
的支持,Drift帮助你保持数据库代码的简洁。 - Safe(安全):Drift基于你的表和查询生成类型安全的代码。如果你在查询中犯了错误,Drift会在编译时发现并提供有帮助且描述性的提示。
- Fast(快速):即使Drift让你编写强大的查询,它的性能也能与键值存储相媲美。Drift是唯一一个带有内置线程支持的主要持久化库,允许你在隔离区之间运行数据库代码而无需额外的努力。
- Reactive(反应式):将任何SQL查询变成自动更新的流!这包括跨多个表的复杂查询。
- Cross-Platform support(跨平台支持):Drift适用于Android、iOS、macOS、Windows、Linux和Web。这个模板是一个可以在所有平台上工作的Flutter待办事项应用程序。
要开始使用drift,请阅读我们详细的文档。
示例代码
下面是一个完整的示例demo,展示了如何使用drift创建一个简单的待办事项应用:
// For more information on using drift, please see https://drift.simonbinder.eu/docs/getting-started/
// A full cross-platform example is available here: https://github.com/simolus3/drift/tree/develop/examples/app
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
part 'main.g.dart';
@DataClassName('TodoCategory')
class TodoCategories extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get name => text()();
}
@TableIndex(name: 'item_title', columns: {#title})
class TodoItems extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get title => text()();
TextColumn get content => text().nullable()();
IntColumn get categoryId => integer().references(TodoCategories, #id)();
TextColumn get generatedText => text().nullable().generatedAs(
title + const Constant(' (') + content + const Constant(')'))();
}
abstract class TodoCategoryItemCount extends View {
TodoItems get todoItems;
TodoCategories get todoCategories;
Expression<int> get itemCount => todoItems.id.count();
@override
Query as() => select([
todoCategories.name,
itemCount,
]).from(todoCategories).join([
innerJoin(todoItems, todoItems.categoryId.equalsExp(todoCategories.id))
]);
}
@DriftView(name: 'customViewName')
abstract class TodoItemWithCategoryNameView extends View {
TodoItems get todoItems;
TodoCategories get todoCategories;
Expression<String> get title =>
todoItems.title +
const Constant('(') +
todoCategories.name +
const Constant(')');
@override
Query as() => select([todoItems.id, title]).from(todoItems).join([
innerJoin(
todoCategories, todoCategories.id.equalsExp(todoItems.categoryId))
]);
}
@DriftDatabase(tables: [
TodoItems,
TodoCategories,
], views: [
TodoCategoryItemCount,
TodoItemWithCategoryNameView,
])
class Database extends _$Database {
Database(super.e);
@override
int get schemaVersion => 2;
@override
MigrationStrategy get migration {
return MigrationStrategy(
onCreate: (m) async {
await m.createAll();
// Add a bunch of default items in a batch
await batch((b) {
b.insertAll(todoItems, [
TodoItemsCompanion.insert(title: 'A first entry', categoryId: 0),
TodoItemsCompanion.insert(
title: 'Todo: Checkout drift',
content: const Value('Drift is a persistence library for Dart '
'and Flutter applications.'),
categoryId: 0,
),
]);
});
},
);
}
// The TodoItem class has been generated by drift, based on the TodoItems
// table description.
//
// In drift, queries can be watched by using .watch() in the end.
// For more information on queries, see https://drift.simonbinder.eu/docs/getting-started/writing_queries/
Stream<List<TodoItem>> get allItems => select(todoItems).watch();
}
Future<void> main() async {
// Create an in-memory instance of the database with todo items.
final db = Database(NativeDatabase.memory());
db.allItems.listen((event) {
print('Todo-item in database: $event');
});
// Add category
final categoryId = await db
.into(db.todoCategories)
.insert(TodoCategoriesCompanion.insert(name: 'Category'));
// Add another entry
await db.into(db.todoItems).insert(TodoItemsCompanion.insert(
title: 'Another entry added later', categoryId: categoryId));
final query = db.select(db.todoItems).join([
innerJoin(db.todoCategories,
db.todoCategories.id.equalsExp(db.todoItems.categoryId))
]);
for (final row in await query.get()) {
print('has row');
print(row.read(db.todoItems.categoryId));
print(row.read(db.todoCategories.name));
}
}
代码说明
-
定义数据表:
TodoCategories
和TodoItems
分别定义了类别表和待办事项表。TodoItems
表中的categoryId
列引用了TodoCategories
表的id
列。
-
定义视图:
TodoCategoryItemCount
视图用于统计每个类别的待办事项数量。TodoItemWithCategoryNameView
视图用于获取待办事项及其所属类别的名称。
-
定义数据库类:
Database
类继承自_Database
,并指定了两个表和两个视图。schemaVersion
定义了数据库版本号。migration
方法定义了数据库创建时的操作,例如创建表和插入初始数据。
-
主函数:
- 创建了一个内存中的数据库实例。
- 监听所有待办事项的变化,并打印出来。
- 插入一个新的类别和一个新的待办事项。
- 查询并打印所有待办事项及其类别信息。
通过这个示例,你可以了解如何使用drift来管理和操作SQLite数据库。更多详细信息请参考官方文档。
更多关于Flutter数据库管理插件drift的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数据库管理插件drift的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用 Drift(以前称为 Floor)数据库管理插件的一个简要指南和代码示例。Drift 是一个强大的、基于 SQLite 的持久化库,为 Flutter 和 Dart 提供类型安全的 ORM(对象关系映射)。
1. 添加 Drift 依赖
首先,在你的 pubspec.yaml
文件中添加 Drift 的依赖:
dependencies:
flutter:
sdk: flutter
drift: ^x.y.z # 请使用最新版本号
然后运行 flutter pub get
来获取依赖。
2. 创建数据库 Schema
接下来,定义一个 Dart 数据类来表示你想要存储的数据模型,并创建一个 Drift 的数据访问对象(DAO)。
import 'package:drift/drift.dart';
part 'user_database.g.dart';
@DriftDatabase(
tables: [Users],
daos: [UserDao]
)
abstract class UserDatabase extends Database {
UserDatabase() : super(
_openConnection(), // 这里你需要定义如何打开数据库连接
);
// 定义数据库连接
static Connection _openConnection() {
// 在实际应用中,你可能需要更复杂的配置
return NativeDatabaseConnection('path_to_your_database.db', loggingEnabled: true);
}
// 用户表定义
@TypeConverters([/* 你的类型转换器,如果有的话 */])
class Users extends Table {
IntColumn get id => integer().primaryKey().autoIncrement()();
TextColumn get name => text().notNull()();
}
}
// 用户 DAO
@Dao(tables: [UserDatabase.Users])
abstract class UserDao {
@Query('SELECT * FROM Users')
Future<List<UserDatabase.Users>> getAllUsers();
@Insert
Future<void> insertUser(UserDatabase.Users user);
@Update
Future<void> updateUser(UserDatabase.Users user);
@Delete
Future<void> deleteUser(UserDatabase.Users user);
}
3. 生成 Drift 代码
在项目的根目录下运行以下命令以生成 Drift 的代码:
flutter pub run build_runner build
这将会生成 user_database.g.dart
文件,其中包含实现你定义的抽象类和表的代码。
4. 使用 Drift 数据库
现在你可以在你的 Flutter 应用中使用 Drift 数据库了。以下是一个简单的示例,展示如何插入和查询用户数据。
import 'package:flutter/material.dart';
import 'user_database.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Drift Example'),
),
body: FutureBuilder<void>(
future: useDatabase(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else {
return Center(child: Text('Database operations completed!'));
}
},
),
),
);
}
Future<void> useDatabase() async {
final db = UserDatabase(_openConnection());
final dao = db.userDao;
// 插入新用户
final newUser = db.users.create()..name = 'John Doe';
await dao.insertUser(newUser);
// 查询所有用户
final users = await dao.getAllUsers();
print('Users in database: ${users.map((user) => user.name).join(', ')}');
// 关闭数据库连接
await db.close();
}
// 这里你需要复制 _openConnection 方法到你的 main.dart 文件或者创建一个全局的数据库连接管理
static Connection _openConnection() {
return NativeDatabaseConnection('path_to_your_database.db', loggingEnabled: true);
}
}
注意事项
- 路径管理:确保数据库文件路径正确,并且在不同的平台上可能需要不同的路径处理方式。
- 错误处理:在生产代码中,添加适当的错误处理和日志记录。
- 线程安全:确保数据库操作在正确的线程或异步环境中执行。
以上就是在 Flutter 中使用 Drift 数据库管理插件的基本步骤和代码示例。希望这对你有所帮助!