sqflite是一个轻量的关系型数据库,以表的形式将较为复杂的数据存储到.db文件中(数据库),同时支持安卓和IOS,简单数据可直接使用 shared_preferences
在pubspec.yaml文件下添加
path_provider是用来处理路径相关的操作
dependencies:
sqflite: ^1.3.0+2
path_provider: ^1.6.9
如果保存了有自动执行则最好,如果没有那么在终端运行flutter packages get命令
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
// SQLite支持的数据类型 不支持bool和DateTime
// SQL类型 ==== Dart类型
// integer ==== int
// real ==== num
// text ==== String
// blob ==== Uint8List
// 数据库文件路径:可以根据自己的需求自己定 这里使用的是外部存储可见的目录
// 可以将路径打印出来 在手机上找到它
String databasePath=(await getExternalStorageDirectory()).path+"/demo.db";
// 打开数据库 (若想数据库只能读取则使用openReadOnlyDatabase())
// 1 若数据库不存在 则创建数据库
// 2 若数据库存在 version大于当前数据库version 则升级
// 3 若数据库存在 version小于当前数据库version 则降级
// 4 若数据库存在 version等于当前数据库version 则不变
Database database=await openDatabase(databasePath,version: 2,
readOnly: false, // 是否只读
singleInstance: true, // 是否单例
// 第一个被调用的可选回调 配置数据库使用SQL语句配置
onConfigure: (Database database)async{
await database.execute("PRAGMA foreign_keys = ON");
print("配置数据库");
},
// 创建数据库回调
onCreate: (Database database,int version)async{
print("版本:$version 数据库创建成功");
},
// 数据库降级回调
onDowngrade: (Database database,int oldVersion,int newVersion)async{
print("版本$oldVersion 降级到 $newVersion");
},
// 数据库升级回调
onUpgrade: (Database database,int oldVersion,int newVersion)async{
print("版本$oldVersion 升级到 $newVersion");
},
// 数据库打开回调
onOpen: (Database database){
print("数据库打开成功");
},
);
// 使用execute方法执行SQL语句 注意:execute执行的SQL是没有返回值的
database.execute('CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT, value INTEGER, age REAL)');
// 在查询和更新删除等语句中,会使用到where和whereArgs作为条件及条件参数
// 此处以查询为例 更新和删除请举一反三
// 查询test表中 name为zs并且age为18的记录
// where中 and代表并且(都满足) or代表或者(满足其一)
// where中的?为占位符 会依照顺序被后面whereArgs中的数据替换
await database.query('test',where:"name=? and age=?",whereArgs: ["zs",18]).then((value) => print(value));
// 插入数据
//1.insert(表名,{"键":值},conflictAlgorithm(冲突算法:枚举类型)) 返回行数
database.insert('test',{"name":'zs',"age":18}).then((value) => print(value));
// 2. 使用SQL语句进行插入
// database.rawInsert("SQL语句");
// 删除数据
// 1.delete("表名",where(条件),whereArgs(条件参数))
// 此处为寻找name为zs的记录
database.delete('test',where: "name=?",whereArgs: ["zs"]);
// 2. 使用SQL语句进行删除
// database.rawDelete("SQL语句");
// 更新数据
// 1.update("表名",要修改的内容{'键':值},where(条件),whereArgs(条件参数),conflictAlgorithm(冲突算法:枚举类型))
// 将name为zs的记录的name改为ls,age改为18
database.update('test', {"name":'ls',"age":18},where: "name=?",whereArgs: ['zs']);
// 2.使用SQL语句进行更新
// database.rawUpdate("SQL语句");
// 查询数据
// 1.query(表名,{distinct,columns(返回哪些字段),where(条件),
// whereArgs(条件参数),groupBy(分组),having(分组后的进行条件查询),
// orderBy(排序),limit(一次读几条),offset(起始位置)}) 返回读取到的结果(列表)
// 若没有查询条件 则返回这个表的数据
await database.query('test', //查询的表名
distinct: true, // 不重复
where:"value=? and age=?",whereArgs: [1,18], // 查询 value为1并且age为18的记录
columns: ["name","age"], // 返回的记录只包含name和age两个字段
groupBy: "age", // 根据age分组
orderBy: "age", // 根据age排序
limit: 10, // 一次读取10条记录
offset: 5 // 从第5条记录开始查询
);
// 2. 使用SQL语句进行查询
// database.rawQuery("SQL语句");
// 批处理SQL语句 往Batch中添加语句 但是这些语句并不会执行 需要调用commit方法 然后一次性执行
Batch batch=database.batch();
batch.insert("test",{"name":'ls'});
batch.insert("test",{"name":'ww'});
// noResult 是否不需要结果 continueOnError遇到异常是否继续执行
batch.commit(noResult: true,continueOnError: true).then((value) => print(value));
// 事务
// 在事务中执行SQL语句 若发生异常 则进行回滚 即全部SQL语句无效
// 四大特征:
// 1. 原子性:即事务中的语句为一个整体 要么全部执行 要么全不执行
// 2. 一致性:保持数据的一致性 如转账 转账过后的总金额需要保持一致
// 3. 隔离性:多个事务并发时 互不干涉内部数据 处理的数据都是别的事务处理前或处理后的数据
// 4. 持久性:事务提交后 数据是持久不可更改的
database.transaction((txn)async{
// txn基本有database中所有的操作 基本可以当做database使用
txn.insert('test',{"name":'Rob'});
});
// 数据库是否打开
// print(database.isOpen);
// 获取默认数据库存放的路径
getDatabasesPath().then((value) => print("默认数据库路径"+value));
// 根据路径查看数据库是否存在
databaseExists(databasePath).then((value) => print("数据库是否存在:"+value.toString()));
// 设置数据库版本
database.setVersion(666);
// 获取数据库版本
database.getVersion().then((value) => print(value));
// 关闭数据库(数据库文件还在)
// database.close();
// 删除数据库(数据库文件不在)
// await deleteDatabase(databasePath);
根据官方文档和源码注解以及尝试所得,若有所帮,点赞一下