Flutter中操作数据库可以通过sqflite来实现,支持事务和批量操作,支持在Android、iOS后台线程执行任务,详见文档 https://pub.dartlang.org/packages/sqflite;
另外可参考 https://www.jianshu.com/p/7ac3ce2bc0c6 ;
对应的demo地址 https://github.com/zhujian1989/flutter_study/blob/master/lib/widget/demo_database/data_page.dart
本文代码参考上面demo作了一些调整。
1、添加依赖
在demo中会用到路径等多个插件库,一并加载
在pubspec.yaml添加
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
event_bus: ^1.0.1
sqflite: ^1.1.0
shared_preferences: ^0.5.1
path_provider: ^0.5.0
dart文件中导入包
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart';
import 'dart:io';
2、数据库的创建、打开
//创建数据库
Future<String> _createNewDb(String dbName) async {
//获取数据库文件路径
var dbPath = await getDatabasesPath();
print('dbPath:' + dbPath);
String path = join(dbPath, dbName);
if (await new Directory(dirname(path)).exists()) {
await deleteDatabase(path);
} else {
try {
await new Directory(dirname(path)).create(recursive: true);
} catch (e) {
print(e);
}
}
return path;
}
_create() async {
dbPath = await _createNewDb(dbName);
Database db = await openDatabase(dbPath);
await db.execute(sql_createTable);
await db.close();
setState(() {
_result = '创建user.db成功,创建user_table成功';
});
}
//打开数据库,获取数据库对象
_open() async {
if(null == dbPath){
var path = await getDatabasesPath();
dbPath = join(path, dbName);
print('dbPath:' + dbPath);
}
return await openDatabase(dbPath);
}
数据库的创建、打开,都需要先获取数据库文件的路径,获取到path之后Database db = await openDatabase(dbPath);
获取数据库对象,注意数据库的操作全都是异步的,要用关键字await。
3、数据库的增删改查
_add() async {
Database db = await _open();
String sql =
"INSERT INTO user_table(username,pwd) VALUES('$username','$pwd')";
//开启事务
await db.transaction((txn) async {
int id = await txn.rawInsert(sql);
});
await db.close();
setState(() {
_result = "插入username=$username,pwd=$pwd数据成功";
});
}
_delete() async {
Database db = await _open();
//删除最近一条
String sql = "DELETE FROM user_table where id in (select id from user_table order by id desc limit 1)";
int count = await db.rawDelete(sql);
await db.close();
setState(() {
if (count == 1) {
_result = "删除成功,请查看";
} else {
_result = "删除0条数据或删除失败,请看log";
}
});
}
_update() async {
Database db = await _open();
String sql = "UPDATE user_table SET pwd = ? WHERE id = ?";
int count = await db.rawUpdate(sql, ["654321", '1']);
print(count);
await db.close();
setState(() {
_result = "更新数据成功,请查看";
});
}
//批量增、改、删数据
_batch() async {
Database db = await _open();
var batch = db.batch();
batch.insert("user_table", {"username": "batchName1"});
batch.update("user_table", {"username": "batchName2"}, where: "username = ?",whereArgs: ["batchName1"]);
batch.delete("user_table", where: "username = ?", whereArgs: ["Leon"]);
//返回每个数据库操作的结果组成的数组 [6, 3, 0]:新增返回id=6,修改了3条数据,删除了0条数据
var results = await batch.commit();
await db.close();
setState(() {
_result = "批量增、改数据成功 "+results.toString();
});
}
_queryNum() async {
Database db = await _open();
int count = Sqflite.firstIntValue(await db.rawQuery(sql_query_count));
await db.close();
setState(() {
_result = "数据条数:$count";
});
}
_query() async {
Database db = await _open();
List<Map> list = await db.rawQuery(sql_query);
await db.close();
setState(() {
_result = "数据详情:$list";
});
}
上面的增加数据代码中开启了事务,可以进行批量插入,每次数据库操作结束都要记得关闭await db.close();
注意,当使用transaction对象访问数据时,不能再使用database对象访问数据库
await database.transaction((txn) async {
await txn.execute("CREATE TABLE Test1 (id INTEGER PRIMARY KEY)");
// 不能在transaction对象里面使用database对象,这会发生死锁
// await database.execute("CREATE TABLE Test2 (id INTEGER PRIMARY KEY)");
});
支持批量操作,但是真正操作被执行是在事务被提交的时候,比如上面代码中的var results = await batch.commit();
后续待补充...
网友评论