Flutter的數據持久化
一起從0開始學習Flutter!
在移動端存儲數據我們有多種方法有sharePreferences,SQLite,本地文件,網絡存儲這幾種方法,後面的兩種在前面的文章中有部分介紹,這裏不多做說明,這篇主要是跟大家一起來學習sharePreferences,SQLite。
sharePreference
這個在原來安卓的開發中經常用到,來看下在Flutter中是否還是我們原來熟悉的sharePreference麼。
首先介紹一下sharePreference的使用,由於是第三方庫我們先將它引入到我們項目中:
dependencies:
shared_preferences: ^0.5.7
引入完成後我們可以在使用時import該類庫
import 'package:shared_preferences/shared_preferences.dart';
引入完成我們就可以進行使用了,先從常規的增刪改查來看下:
增:
//在實例化的時候需要讀取本地已經持久化的數據來讀到內存中,有可能會耗時比較多,這裏它採用了異步的方式,所以需要加await關鍵字,在引用它的方法聲明上添加async關鍵字
SharedPreferences sharePerence = await SharedPreferences.getInstance();
sharePerence.setString("key1", "value1");
//這裏存儲了一個字符串,還可以存儲其他類型的數據:
sharePerence.setBool(key, value);
sharePerence.setDouble(key, value);
sharePerence.setInt(key, value);
sharePerence.setStringList(key, value);
刪:
sharePerence.remove(key);//刪除比較簡單
改:
改的方法同增加的方式,如果發現了重複的key則會對原來的值進行覆蓋。
查:
sharePerence.containsKey(key);//是否包含指定key的值
它是怎麼在本地進行存儲的呢?它會生成一個xml放置到本地的沙盒中,打開裏面看到存儲的數據結構是:
<map>
<string name="flutter.key1">value1</string>
</map>
也就是說我們所有的shareperfence都是存儲在這一個xml中的,聯想到xml的讀取和寫入方式,在存儲到大量的數據後讀取速度就會有比較大的影響,這裏不建議存放過多的數據。
SQLite
存儲大量數據的時候它就比較合適了,我們可以看下它是如何幫我們存儲大量的數據的。
我們先引入SQLite的第三方庫:
dependencies:
sqflite: ^1.3.0
在需要使用的地方import該類庫:
import 'package:sqflite/sqflite.dart';
完成引用後就可以開始使用了,先看下如何操作一個數據庫,直接使用openDatabase方法就可以直接打開一個數據庫,一起看下如何創建和升級表:
Future<Database> openDatabase(String path,//需要打開的數據庫名稱
{int version,//最新的數據庫版本
OnDatabaseConfigureFn onConfigure,//參照下面的詳解
OnDatabaseCreateFn onCreate,//參照下面的詳解
OnDatabaseVersionChangeFn onUpgrade,//參照下面的詳解
OnDatabaseVersionChangeFn onDowngrade,//參照下面的詳解
OnDatabaseOpenFn onOpen,//參照下面的詳解
bool readOnly = false,//是否是隻讀模式
bool singleInstance = true})//是否數據庫是單例的,如果是單例的我們傳入地址是一個的時候則會返回剛剛實例的數據庫
onConfigure
在回調onCreate/onUpdate/onOpen之前會調用該方法,我們可以在這裏做一些初始化的工作。onConfigure的類型爲OnDatabaseConfigureFn,我們看下OnDatabaseConfigureFn是什麼:
typedef OnDatabaseConfigureFn = FutureOr<void> Function(Database db);//這裏我們需要傳入一個帶有Database參數的函數來處理初始需要做的事情
onCreate
在完成了onConfigure的回調後開始調用OnCreate方法,在這裏我們可以創建表,還是看下OnDatabaseCreateFn是什麼:
typedef OnDatabaseCreateFn = FutureOr<void> Function(Database db, int version);//這裏我們需要一個傳入一個帶有DataBase和version的函數來處理初始化,可以根據version來創建表
我們先在這步進行一個數據庫的創建爲了以後我們好看接下里的實例:
onCreate: (dataBase, version) {
dataBase.execute("create table my_table (id integer primary key,username text,password text)");//創建一個my_table的表
}
onUpgrade
在版本號我們更新了以後會調用onUpgrade的方法,如果發生了表內字段的變更我們可以在這裏根據版本號進行判斷,針對不同的版本設定字段更新語句。看下OnDatabaseVersionChangeFn是什麼:
typedef OnDatabaseVersionChangeFn = FutureOr<void> Function(
Database db, int oldVersion, int newVersion);//這裏我們需要一個傳入一個帶有DataBase、oldversion和newVersion的函數來處理初始化,可以根據oldVersion,newVersion來修改表結構
onDowngrade
如果出現newVersion低於了oldVersion的版本會調用onDowngrade的方法,調用的時候可以根據降級的版本進行數據表的恢復。傳入的也是OnDatabaseVersionChangeFn,可以參照上面的。
打開了一個數據庫之後我們就可以對數據庫進行操作了,我們還是從常規的增刪改查來看下:
增:
dataBase.execute(
"insert into my_table(username,password) values(?,?);",["flutter","pwd1"]);//增加一條數據
刪:
int deleteCount = await dataBase.rawDelete("delete from my_table where username=?",["flutter"]);//返回影響的行數
改:
int updateCount = await dataBase.rawUpdate("update my_table set password = ? where username = ?",["pwd2","flutter"]);//返回影響的行數
查:
List<Map> dataList = await dataBase.rawQuery("select * from my_table where username= ?",["flutter"]);//返回所有的查詢結果,以剛剛的插入數據的SQL爲例,返回的結果爲:[{id: 1, username: flutter, password: pwd1}]
在我們使用完數據庫之後一定要記得關閉數據庫,避免資源的浪費,關閉數據庫:
dataBase.close();
如果我們想要刪除一個表就可以根在OnCreate裏的操作一樣使用execute方法:
dataBase.execute("drop table my_table");
如果我們想要執行多條數據庫指令,需要使用到SQL中的事務來幫助我們保證數據的一致性:
dataBase.transaction((txn) async {
var batch = txn.batch();
batch.rawInsert("insert into my_table(username,password) values(?,?)",["flutter1","pwd2"]);
batch.rawInsert("insert into my_table(username,password) values(?,?)",["flutter2","pwd3"]);
batch.rawInsert("insert into my_table(username,password) values(?,?)",["flutter3","pwd4"]);
batch.commit(noResult: true);//一併插入三條數據,並不需要返回結果
});
數據庫的基本操作就介紹完了,在實際使用的過程中這樣的使用是不太符合我們日常習慣的,最好還是根據面向對象的方式將增刪改查的方式封裝到對象裏。