前言
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);
根據官方文檔和源碼註解以及嘗試所得,若有所幫,點贊一下