Flutter持久化存储之sqflite操作数据库详细使用

前言

sqflite是一个轻量的关系型数据库,以表的形式将较为复杂的数据存储到.db文件中(数据库),同时支持安卓和IOS,简单数据可直接使用 shared_preferences

1. 准备工作

1.1 添加依赖:

在pubspec.yaml文件下添加
path_provider是用来处理路径相关的操作
dependencies:
  sqflite: ^1.3.0+2
  path_provider: ^1.6.9

1.2 安装

如果保存了有自动执行则最好,如果没有那么在终端运行flutter packages get命令

1.3 导入

import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';

1.4 注意

 // SQLite支持的数据类型  不支持bool和DateTime
 // SQL类型 ==== Dart类型
 // integer ==== int
 // real    ==== num
 // text    ==== String
 // blob    ==== Uint8List

2. 使用流程

2.1 创建数据库

// 数据库文件路径:可以根据自己的需求自己定 这里使用的是外部存储可见的目录
// 可以将路径打印出来 在手机上找到它
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("数据库打开成功");
  },
);

2.2 创建数据表

// 使用execute方法执行SQL语句 注意:execute执行的SQL是没有返回值的
database.execute('CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT, value INTEGER, age REAL)');

2.3 增删改查

2.3.1 where和whereArgs的使用
// 在查询和更新删除等语句中,会使用到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));
2.3.2 插入数据
// 插入数据  
//1.insert(表名,{"键":值},conflictAlgorithm(冲突算法:枚举类型)) 返回行数
database.insert('test',{"name":'zs',"age":18}).then((value) => print(value));
// 2. 使用SQL语句进行插入 
// database.rawInsert("SQL语句");
2.3.3 删除数据
// 删除数据 
// 1.delete("表名",where(条件),whereArgs(条件参数))
// 此处为寻找name为zs的记录
database.delete('test',where: "name=?",whereArgs: ["zs"]);  
// 2. 使用SQL语句进行删除
// database.rawDelete("SQL语句");
2.3.4 更新数据
// 更新数据
// 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语句");
2.3.5 查询数据
// 查询数据
// 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语句");

2.4 批处理 Batch

// 批处理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));

2.5 事务

// 事务
// 在事务中执行SQL语句 若发生异常 则进行回滚 即全部SQL语句无效
// 四大特征:
// 1. 原子性:即事务中的语句为一个整体 要么全部执行 要么全不执行
// 2. 一致性:保持数据的一致性 如转账 转账过后的总金额需要保持一致
// 3. 隔离性:多个事务并发时  互不干涉内部数据 处理的数据都是别的事务处理前或处理后的数据
// 4. 持久性:事务提交后 数据是持久不可更改的

database.transaction((txn)async{
  // txn基本有database中所有的操作 基本可以当做database使用
  txn.insert('test',{"name":'Rob'});
});

2.6 其他数据库操作

// 数据库是否打开
// 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);

根据官方文档和源码注解以及尝试所得,若有所帮,点赞一下

你可能感兴趣的:(Flutter,Flutter,sqflite,数据库)