Flutter数据库管理插件sqlbrite的使用
Flutter数据库管理插件sqlbrite的使用
SQL Brite
SQL Brite 是一个为Flutter设计的,基于 sqflite
的响应式流包装库,灵感来源于 sqlbrite。它引入了响应式流语义到SQL操作中,使得在Flutter应用中处理数据库更加简单和直观。
作者
特点
- 响应式流包装
sqflite
- 支持流式
sqflite
- 基于 RxDart 的响应式流
sqflite
库 - 轻量级的
sqflite
包装,引入了响应式流语义到SQL操作中
开始使用
依赖配置
在你的Flutter项目中,在 pubspec.yaml
文件中添加依赖:
dependencies:
...
sqlbrite: ^latest_version # 替换为最新版本号
安装依赖
通过命令行安装依赖:
$ flutter packages get
导入库
在Dart代码中导入 sqlbrite
:
import 'package:sqlbrite/sqlbrite.dart';
使用方法
1. 将数据库包装成 BriteDatabase
final Database db = await openDb();
final briteDb = BriteDatabase(db);
// 禁用日志记录
final briteDb = BriteDatabase(db, logger: null);
2. 使用 BriteDatabase
创建实体模型
class Entity {
factory Entity.fromJson(Map<String, dynamic> map) { ... }
factory Entity.empty() { ... }
Map<String, dynamic> toJson() { ... }
}
使用 mapToOne
扩展方法
// 发射单个行,如果行不存在或结果集中有多个行则发射错误。
final Stream<Entity> singleQuery$ = briteDb.createQuery(
'table',
where: 'id = ?',
whereArgs: [id],
limit: 1,
).mapToOne((row) => Entity.fromJson(row));
使用 mapToOneOrDefault
扩展方法
// 发射单个行,如果行不存在则发射给定的默认值,如果有多个行则发射错误。
final Stream<Entity> singleOrDefaultQuery$ = briteDb.createQuery(
'table',
where: 'id = ?',
whereArgs: [id],
limit: 1,
).mapToOneOrDefault(
(row) => Entity.fromJson(row),
defaultValue: Entity.empty()
);
使用 mapToList
扩展方法
// 发射行列表。
final Stream<List<Entity>> listQuery$ = briteDb.createQuery(
'table',
where: 'name LIKE ?',
whereArgs: [queryName],
).mapToList((row) => Entity.fromJson(row));
类似 Database
的API
// 插入数据会触发查询流重新执行
briteDb.insert(
'table',
Entity(...).toJson()
);
// 更新数据会触发查询流重新执行
briteDb.update(
'table',
Entity(...).toJson(),
where: 'id = ?',
whereArgs: [id],
);
// 删除数据会触发查询流重新执行
briteDb.delete(
'table',
where: 'id = ?',
whereArgs: [id],
);
使用 RxDart 操作符
briteDb
.createQuery(
'table',
where: 'name LIKE ?',
whereArgs: [queryName],
)
.debounceTime(const Duration(milliseconds: 500))
.where(filterQuery) // 查询是惰性的,这允许你根据需要决定是否执行查询
.mapToList((row) => Entity.fromJson(row))
.listen(updateUI);
示例代码
以下是一个完整的示例代码,展示了如何在Flutter应用中使用 sqlbrite
:
import 'package:flutter/material.dart';
import 'package:sqlbrite/sqlbrite.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final database = await openDatabase('example.db');
final briteDb = BriteDatabase(database);
runApp(MyApp(briteDb: briteDb));
}
class MyApp extends StatelessWidget {
final BriteDatabase briteDb;
const MyApp({super.key, required this.briteDb});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData.dark(),
home: MyHomePage(briteDb: briteDb),
);
}
}
class MyHomePage extends StatefulWidget {
final BriteDatabase briteDb;
const MyHomePage({super.key, required this.briteDb});
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late Stream<List<Map<String, dynamic>>> queryStream;
@override
void initState() {
super.initState();
queryStream = widget.briteDb.createQuery('items').mapToList((row) => row);
}
void addItem() async {
await widget.briteDb.insert('items', {'name': 'Item ${DateTime.now()}'});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('SQL Brite Example')),
body: StreamBuilder<List<Map<String, dynamic>>>(
stream: queryStream,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
}
final items = snapshot.data!;
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return ListTile(title: Text(item['name']));
},
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: addItem,
child: Icon(Icons.add),
),
);
}
}
哲学
SQL Brite 的唯一职责是协调和组合表更新的通知,以便在数据更改时立即更新查询。它不是一个ORM,也不是类型安全的查询机制,也不会为你执行数据库迁移。
许可证
MIT License Copyright © 2019 - 2022 Petrus Nguyễn Thái Học
更多关于Flutter数据库管理插件sqlbrite的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数据库管理插件sqlbrite的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用sqlbrite
进行数据库管理的示例代码。不过需要注意的是,sqlbrite
本身是一个用于Android的SQLite扩展库,它提供了响应式数据库访问能力。由于Flutter主要使用Dart语言,并且有自己的插件生态系统,通常我们会使用像sqflite
或floor
这样的插件来管理SQLite数据库。
然而,如果你确实想在Flutter项目中使用sqlbrite
(尽管这不是最常见的做法),你通常会通过平台通道(Platform Channel)与原生Android代码进行交互。以下是一个简化的示例,展示如何在Flutter项目中集成sqlbrite
。
1. 设置Flutter项目
首先,创建一个新的Flutter项目:
flutter create flutter_sqlbrite_example
cd flutter_sqlbrite_example
2. 在Android原生代码中集成sqlbrite
打开android/app/src/main/java/com/your_company_name/flutter_sqlbrite_example/
目录,并创建一个新的Kotlin文件,例如SqlBriteHelper.kt
:
package com.your_company_name.flutter_sqlbrite_example
import android.content.Context
import com.squareup.sqlbrite2.BriteDatabase
import com.squareup.sqlbrite2.SqlBrite
import java.util.concurrent.Executors
class SqlBriteHelper(context: Context) {
private val sqlBrite: SqlBrite = SqlBrite.create()
private val db: BriteDatabase = sqlBrite.wrapDatabaseHelper(
context,
"my_database.db",
1
) { db ->
// Create tables here if needed
db.execSQL("CREATE TABLE IF NOT EXISTS example (id INTEGER PRIMARY KEY, name TEXT)")
}
fun insert(name: String) {
db.insert("example", null, hashMapOf("name" to name))
}
fun queryAll(): List<Map<String, Any?>> {
return db.query("SELECT * FROM example").map { cursor ->
hashMapOf(
"id" to cursor.getLong(cursor.getColumnIndexOrThrow("id")),
"name" to cursor.getString(cursor.getColumnIndexOrThrow("name"))
)
}.toList()
}
}
3. 创建平台通道
在MainActivity.kt
中设置平台通道以与Flutter代码通信:
package com.your_company_name.flutter_sqlbrite_example
import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterActivity() {
private val CHANNEL = "com.your_company_name.flutter_sqlbrite_example/channel"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
if (call.method == "insert") {
val sqlBriteHelper = SqlBriteHelper(applicationContext)
val name = call.argument<String>("name") ?: ""
sqlBriteHelper.insert(name)
result.success(null)
} else if (call.method == "queryAll") {
val sqlBriteHelper = SqlBriteHelper(applicationContext)
val items = sqlBriteHelper.queryAll()
result.success(items)
} else {
result.notImplemented()
}
}
}
}
4. 在Flutter代码中调用平台通道
打开lib/main.dart
,设置与原生代码的通信:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
static const platform = MethodChannel('com.your_company_name.flutter_sqlbrite_example/channel');
List<Map<String, dynamic>> _items = [];
@override
void initState() {
super.initState();
_queryAll();
}
Future<void> _insertItem(String name) async {
try {
await platform.invokeMethod('insert', {'name': name});
setState(() {
_queryAll();
});
} on PlatformException catch (e) {
print("Failed to insert item: '${e.message}'.");
}
}
Future<void> _queryAll() async {
try {
final result = await platform.invokeMethod('queryAll');
setState(() {
_items = result.cast<Map<String, dynamic>>();
});
} on PlatformException catch (e) {
print("Failed to query items: '${e.message}'.");
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter SQLBrite Example'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
itemCount: _items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('ID: ${_items[index]['id']}, Name: ${_items[index]['name']}'),
);
},
),
),
TextField(
decoration: InputDecoration(labelText: 'Enter name'),
onSubmitted: (name) {
_insertItem(name);
},
),
],
),
),
),
);
}
}
总结
上述代码展示了如何在Flutter项目中通过平台通道与原生Android代码集成,并在原生代码中使用sqlbrite
进行数据库管理。然而,请注意,这种方法并不是最常见的做法,因为Flutter有自己的数据库管理插件,如sqflite
或floor
,它们更适合Flutter生态系统。如果你确实需要在Flutter中使用sqlbrite
的特定功能,上述方法提供了一种可行的解决方案。