如何在Flutter中使用Isar本地存储数据
在构建Flutter应用程序时,高效管理本地数据至关重要。您需要一个轻量级、快速且易于集成的数据库,特别是在应用需要离线工作时。Isar就是这样一个数据库。它是一个专为Flutter定制的高性能、易用的NoSQL嵌入式数据库。具有响应式查询、索引、关系、迁移和事务等特性,Isar使本地数据持久化既强大又对开发者友好。
在本文中,您将学习如何将Isar集成到Flutter项目中,设置数据模型,并执行完整的CRUD(创建、读取、更新、删除)操作。为了使其更实用,您将构建一个简单的待办事项应用,允许用户创建、查看、更新和删除任务。
目录
- 先决条件
- 我们将构建什么
- 如何在Flutter项目中设置Isar
- 如何创建任务模型
- 如何构建CRUD操作的数据仓库
- 如何将CRUD集成到Flutter UI中
- 超越CRUD:Isar的高级特性
- 结论
先决条件
开始之前,请确保您具备以下条件:
-
已安装Flutter SDK(建议版本3.0或以上)。使用以下命令检查您的版本:
-
Dart知识:熟悉Dart语法、类和异步编程。
-
Flutter基础:您应该知道如何设置Flutter项目、构建小部件,以及使用FutureBuilder或setState进行状态管理。
-
代码编辑器:推荐使用VS Code或Android Studio。
如果这些都准备好了,我们就可以开始了。
我们将构建什么
我们将创建一个任务管理器应用,让用户能够:
- 添加新任务。
- 在列表中查看所有任务。
- 更新现有任务。
- 删除任务。
到最后,您将拥有一个使用Flutter和Isar构建的完全功能的CRUD应用。
如何在Flutter项目中设置Isar
步骤1:添加依赖
打开您的pubspec.yaml文件并添加以下内容:
1
2
3
4
5
6
7
8
9
|
dependencies:
flutter:
sdk: flutter
isar: ^3.1.0
isar_flutter_libs: ^3.1.0
dev_dependencies:
isar_generator: ^3.1.0
build_runner: any
|
isar
: 核心Isar包。
isar_flutter_libs
: Flutter集成所需。
isar_generator
: 用于为模型生成代码。
build_runner
: 运行代码生成器。
运行:
步骤2:创建并初始化Isar
创建一个名为isar_setup.dart
的文件。这将处理Isar数据库的打开。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import 'package:isar/isar.dart';
import 'package:path_provider/path_provider.dart';
import 'task.dart'; // 我们很快将创建此模型
late final Isar isar;
Future<void> initializeIsar() async {
final dir = await getApplicationDocumentsDirectory();
isar = await Isar.open(
[TaskSchema],
directory: dir.path,
);
}
|
解释:
getApplicationDocumentsDirectory()
提供数据库文件的存储位置。
Isar.open()
初始化数据库并注册我们的Task模式。
late final Isar isar;
确保我们在初始化后可以全局访问数据库实例。
如何创建任务模型
现在让我们为任务定义数据模型。创建一个名为task.dart
的文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import 'package:isar/isar.dart';
part 'task.g.dart';
@Collection()
class Task {
Id id = Isar.autoIncrement; // 自动递增的主键
late String name;
late DateTime createdAt;
Task(this.name) : createdAt = DateTime.now();
}
|
解释:
@Collection()
告诉Isar这个类代表一个数据库集合。
Id id = Isar.autoIncrement;
自动创建一个唯一标识符。
late String name;
存储任务名称。
late DateTime createdAt;
存储创建时间戳。
part 'task.g.dart';
链接到生成的代码,该代码将在运行代码生成器后创建。
使用以下命令生成代码:
1
|
flutter pub run build_runner build
|
这将生成task.g.dart
,其中包含必要的模式代码。
如何构建CRUD操作的数据仓库
创建一个名为task_repository.dart
的新文件。这将包含与数据库交互的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
import 'package:isar/isar.dart';
import 'task.dart';
import 'isar_setup.dart';
class TaskRepository {
Future<void> addTask(String name) async {
final task = Task(name);
await isar.writeTxn(() async {
await isar.tasks.put(task);
});
}
Future<List<Task>> getAllTasks() async {
return await isar.tasks.where().findAll();
}
Future<void> updateTask(Task task) async {
await isar.writeTxn(() async {
await isar.tasks.put(task);
});
}
Future<void> deleteTask(Task task) async {
await isar.writeTxn(() async {
await isar.tasks.delete(task.id);
});
}
}
|
解释:
addTask
:创建新任务并保存。
getAllTasks
:从数据库中读取所有任务。
updateTask
:通过再次调用.put()
来更新现有任务。
deleteTask
:通过其id删除任务。
isar.writeTxn
:确保操作在事务内运行,以保证安全性和一致性。
如何将CRUD集成到Flutter UI中
现在,让我们在main.dart
中连接所有内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
import 'package:flutter/material.dart';
import 'isar_setup.dart';
import 'task_repository.dart';
import 'task.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await initializeIsar(); // 在runApp之前初始化Isar
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: TaskListScreen(),
);
}
}
class TaskListScreen extends StatefulWidget {
@override
_TaskListScreenState createState() => _TaskListScreenState();
}
class _TaskListScreenState extends State<TaskListScreen> {
final TaskRepository _taskRepository = TaskRepository();
late Future<List<Task>> _tasksFuture;
@override
void initState() {
super.initState();
_tasksFuture = _taskRepository.getAllTasks();
}
Future<void> _addTask() async {
await _taskRepository.addTask('New Task');
setState(() {
_tasksFuture = _taskRepository.getAllTasks();
});
}
Future<void> _deleteTask(Task task) async {
await _taskRepository.deleteTask(task);
setState(() {
_tasksFuture = _taskRepository.getAllTasks();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Isar CRUD Example')),
body: FutureBuilder<List<Task>>(
future: _tasksFuture,
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 tasks = snapshot.data ?? [];
if (tasks.isEmpty) {
return Center(child: Text('No tasks yet.'));
}
return ListView.builder(
itemCount: tasks.length,
itemBuilder: (context, index) {
final task = tasks[index];
return ListTile(
title: Text(task.name),
subtitle: Text('Created at: ${task.createdAt}'),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () => _deleteTask(task),
),
);
},
);
}
},
),
floatingActionButton: FloatingActionButton(
onPressed: _addTask,
child: Icon(Icons.add),
),
);
}
}
|
解释:
initializeIsar()
:确保在应用运行前数据库已准备就绪。
_tasksFuture
:保存任务列表的Future。
_addTask
:添加新任务并刷新列表。
_deleteTask
:删除任务并刷新列表。
FutureBuilder
:当future完成时自动重建UI。
ListView.builder
:动态显示所有任务。
这为您提供了一个使用Isar的简单而完整的CRUD应用。
超越CRUD:Isar的高级特性
一旦您熟悉了CRUD,Isar提供了高级工具来优化和扩展您的应用:
结论
我们使用Isar构建了一个简单的Flutter待办事项应用,支持创建、读取、更新和删除任务。在此过程中,我们学习了如何:
- 添加Isar依赖。
- 使用注解定义模型。
- 生成模式代码。
- 在仓库中实现CRUD操作。
- 将Isar连接到Flutter UI。
凭借其性能、对开发者友好的API和高级特性,Isar是Flutter应用中本地持久化的绝佳选择。
如需进一步学习,请查阅官方文档: