Flutter嵌入式数据库插件unqlite_flutter的使用
Flutter嵌入式数据库插件unqlite_flutter的使用
UnQLite 数据库插件为 Flutter 而封装。UnQLite 是一个嵌入式的 NoSQL 数据库,详情请见 此处。
注意:目前仅支持键值存储。
待办事项:
- ✅ 键值存储
- ✅ JSON 文档存储
使用方法
键值存储
添加依赖项:
dependencies:
unqlite: latest
unqlite_flutter: latest
简单的键值存储示例:
import 'dart:io' show Platform;
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:unqlite/unqlite.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Future<void> testUnqlite() async {
var appDocDir = await getApplicationDocumentsDirectory();
final start = DateTime.now().millisecondsSinceEpoch;
// 创建或打开数据库
UnQLite db = UnQLite.open("${appDocDir.path}/test.db");
// 保存键值对
db.store("name", "Alex");
db.store("age", 18);
db.store(19, "haha");
// 通过键获取值
// 注意:你必须指定值的泛型类型
debugPrint(db.fetch<String>("name"));
debugPrint('${db.fetch<int>("age")}');
debugPrint(db.fetch<String>(19));
// 另一种获取值的方式
db.fetchCallback<int>("age", (val) {
debugPrint('age=$val');
});
// 另一种获取数据的方式,可能比 fetch 更快:
var cursor = db.cursor();
cursor.seek('name');
debugPrint('=> ${cursor.key} => ${cursor.value}');
// 使用事务,这是一个很棒的功能:
var trans = db.transaction().begin();
try {
for (var i = 0; i < 100000; i++) {
if (i == 10) {
// 这里生成一个异常
throw Exception('test');
}
db.store("transaction_$i", "here is a transaction_$i");
}
trans.commit();
} catch (e) {
// 事务在此处回滚
trans.rollback();
}
// 使用迭代器遍历所有数据
for (var entry in db.cursor()) {
var content = '${entry.key} => ${entry.value}';
debugPrint(content);
}
db.close();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('UnQLite app'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: () {
testUnqlite();
},
child: Text('测试UnQLite'),
),
],
),
),
),
);
}
}
JSON 存储
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:unqlite/unqlite.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Future<void> testJSON() async {
var appDocDir = await getApplicationDocumentsDirectory();
final start = DateTime.now().millisecondsSinceEpoch;
UnQLite db = UnQLite.open("${appDocDir.path}/test2.db");
var users = db.collection("users");
users.create();
// 保存 JSON 数据
users.store(jsonDecode('''
{
"title": "test json string",
"author": [
"arcticfox1919"
],
"year": 2022,
"like": "flutter"
}
'''));
users.store({'name': 'Mickey', 'age': 17});
users.store([
{'name': 'Alice', 'age': 18},
{'name': 'Bruce', 'age': 19},
{'name': 'Charlie', 'age': 20},
]);
// 获取所有数据
print(users.all());
// print(users.fetch(0));
// print(users.fetch(1));
// print(users.fetch(2));
// print(users.errorLog());
print(users.creationDate());
print(users.len());
print(users.fetchCurrent());
// 删除所有数据
users.drop();
db.close();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('UnQLite app'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: () {
testJSON();
},
child: Text('测试JSON存储'),
),
],
),
),
),
);
}
}
为什么使用它?
- 比 Hive 更快,并且占用更少的内存。
- 支持 JSON 文档。
缺点:由于使用了 Dart FFI,因此无法在 Web 上使用。
以下是性能测试数据(未列出内存百分比,但可以肯定的是 UnQLite 占用的内存更少):
UnQLite 性能数据:
UnQLite init:1 ms
write 100,000 entries :611 ms
fetch 100,000 entries :370 ms
seek 100,000 entries :215 ms
iterate 100,000 entries :225 ms
transaction rollback :39 ms
Hive 性能数据:
Hive init:48 ms
put 100,000 entries :807 ms
get 100,000 entries :290 ms
下面是用于性能测试的代码,均在相同的手机上以 profile 模式运行:
testUnQLite() async {
var appDocDir = await getApplicationDocumentsDirectory();
final start = DateTime.now().millisecondsSinceEpoch;
UnQLite db = UnQLite.open("${appDocDir.path}/test.db");
final t1 = DateTime.now().millisecondsSinceEpoch;
for (var i = 0; i < 100000; i++) {
db.store("my_key_$i", "Here is a value for testing—$i");
}
final t2 = DateTime.now().millisecondsSinceEpoch;
for (var i = 0; i < 100000; i++) {
var r = db.fetch<String>("my_key_$i");
// debugPrint("fetch :$r");
}
final t3 = DateTime.now().millisecondsSinceEpoch;
var cursor = db.cursor();
for (var i = 0; i < 100000; i++) {
cursor.seek('my_key_$i');
// debugPrint('=> ${cursor.key} => ${cursor.value}');
}
final t4 = DateTime.now().millisecondsSinceEpoch;
var count = 0;
for (var entry in db.cursor()) {
count++;
var content = '${entry.key} => ${entry.value}';
// debugPrint(content);
}
print('count => $count');
final t5 = DateTime.now().millisecondsSinceEpoch;
var trans = db.transaction().begin();
try {
for (var i = 0; i < 100000; i++) {
if (i == 10) {
throw Exception('test');
}
db.store("transaction_$i", "here is a transaction_$i");
}
trans.commit();
} catch (e) {
trans.rollback();
}
final t6 = DateTime.now().millisecondsSinceEpoch;
debugPrint("UnQLite init:${t1 - start} ms");
debugPrint("write 100,000 entries :${t2 - t1} ms");
debugPrint("fetch 100,000 entries :${t3 - t2} ms");
debugPrint("seek 100,000 entries :${t4 - t3} ms");
debugPrint("iterate 100,000 entries :${t5 - t4} ms");
debugPrint("transaction rollback :${t6 - t5} ms");
db.close();
}
testHive() async {
var appDocDir = await getApplicationDocumentsDirectory();
var path = appDocDir.path;
final start = DateTime.now().millisecondsSinceEpoch;
Hive.init(path);
var box = await Hive.openBox('testBox');
final t1 = DateTime.now().millisecondsSinceEpoch;
for (var i = 0; i < 100000; i++) {
box.put("my_key_$i", "here is a transaction_$i");
}
final t2 = DateTime.now().millisecondsSinceEpoch;
for (var i = 0; i < 100000; i++) {
var name = box.get('my_key_$i');
}
final t3 = DateTime.now().millisecondsSinceEpoch;
box.close();
debugPrint("Hive init:${t1 - start} ms");
debugPrint("put 100,000 entries :${t2 - t1} ms");
debugPrint("get 100,000 entries :${t3 - t2} ms");
}
更多关于Flutter嵌入式数据库插件unqlite_flutter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter嵌入式数据库插件unqlite_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
unqlite_flutter
是一个 Flutter 插件,允许你在 Flutter 应用中使用 UnQLite 嵌入式数据库。UnQLite 是一个轻量级的 NoSQL 数据库引擎,支持键值存储和文档存储(JSON 格式)。
以下是如何在 Flutter 项目中使用 unqlite_flutter
插件的步骤:
1. 添加依赖
首先,在你的 pubspec.yaml
文件中添加 unqlite_flutter
依赖:
dependencies:
flutter:
sdk: flutter
unqlite_flutter: ^0.1.0 # 请检查最新版本
然后运行 flutter pub get
来获取依赖。
2. 导入包
在你的 Dart 文件中导入 unqlite_flutter
包:
import 'package:unqlite_flutter/unqlite_flutter.dart';
3. 初始化数据库
在你的应用中使用 UnQLite
类来初始化数据库。通常,你可以在 main
函数或某个初始化方法中进行初始化。
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化 UnQLite 数据库
UnQLite unqlite = UnQLite();
await unqlite.open('my_database.db');
runApp(MyApp());
}
4. 数据库操作
你可以使用 UnQLite
类提供的方法进行数据库操作,例如插入、查询、更新和删除数据。
插入数据
await unqlite.insert('key1', 'value1');
查询数据
String? value = await unqlite.get('key1');
print(value); // 输出: value1
更新数据
await unqlite.update('key1', 'new_value1');
删除数据
await unqlite.delete('key1');
关闭数据库
在应用关闭或不再需要数据库时,记得关闭数据库:
await unqlite.close();
5. 处理 JSON 数据
UnQLite 支持存储 JSON 格式的数据。你可以使用 jsonEncode
和 jsonDecode
来处理 JSON 数据。
import 'dart:convert';
// 插入 JSON 数据
Map<String, dynamic> data = {'name': 'John', 'age': 30};
await unqlite.insert('user1', jsonEncode(data));
// 查询 JSON 数据
String? jsonString = await unqlite.get('user1');
if (jsonString != null) {
Map<String, dynamic> user = jsonDecode(jsonString);
print(user['name']); // 输出: John
}
6. 错误处理
在使用 unqlite_flutter
时,建议对可能出现的异常进行处理。
try {
await unqlite.insert('key1', 'value1');
} catch (e) {
print('Error: $e');
}
7. 使用 Provider 或 Riverpod 进行状态管理
如果你在你的 Flutter 应用中使用状态管理工具(如 Provider 或 Riverpod),你可以将 UnQLite
实例封装在状态管理类中,以便在整个应用中访问数据库。
8. 示例代码
以下是一个简单的示例,展示了如何在 Flutter 应用中使用 unqlite_flutter
插件:
import 'package:flutter/material.dart';
import 'package:unqlite_flutter/unqlite_flutter.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
UnQLite unqlite = UnQLite();
await unqlite.open('my_database.db');
runApp(MyApp(unqlite: unqlite));
}
class MyApp extends StatelessWidget {
final UnQLite unqlite;
MyApp({required this.unqlite});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('UnQLite Demo')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async {
await unqlite.insert('key1', 'value1');
print('Data inserted');
},
child: Text('Insert Data'),
),
ElevatedButton(
onPressed: () async {
String? value = await unqlite.get('key1');
print('Fetched Data: $value');
},
child: Text('Fetch Data'),
),
],
),
),
),
);
}
}