Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
幾乎每個(gè)應(yīng)用程序都需要在本地存儲(chǔ)數(shù)據(jù)。信息的存儲(chǔ)和操作是應(yīng)用程序開(kāi)發(fā)的重要組成部分,F(xiàn)lutter 應(yīng)用程序也是如此。也許您想要緩存 REST API 響應(yīng)、構(gòu)建離線運(yùn)行的應(yīng)用程序或存儲(chǔ)食品配送應(yīng)用程序的客戶信息。
開(kāi)發(fā)人員可以使用多種選項(xiàng)在 Flutter 中持久化本地?cái)?shù)據(jù)。shared_preferences:提供了一種很好的方法來(lái)存儲(chǔ)小對(duì)鍵和值。sqflite:當(dāng)您的數(shù)據(jù)庫(kù)必須處理關(guān)系數(shù)據(jù)之間的復(fù)雜關(guān)系時(shí),這是一個(gè)不錯(cuò)的選擇。
但是,如果您正在尋找一個(gè)快速且安全的本地?cái)?shù)據(jù)庫(kù),并且還與 Flutter Web() 兼容,那么在這種情況下,使用Flutter hive 處理離線數(shù)據(jù)存儲(chǔ)是最好的方法之一。
Flutter 中的 Hive 是什么?
Hive 是一個(gè)用純 Dart 編寫的輕量級(jí)快速鍵值數(shù)據(jù)庫(kù),它允許您離線存儲(chǔ)和同步應(yīng)用程序數(shù)據(jù)。
作為用 Dart 編寫的鍵值數(shù)據(jù)存儲(chǔ),Hive 支持原始和復(fù)雜的數(shù)據(jù)結(jié)構(gòu),同時(shí)提供最高級(jí)別的性能。
此外,它還使用 AES-256 加密。
作為示例,這是一張將 Flutter Hive 與其他類似數(shù)據(jù)庫(kù)進(jìn)行比較的圖表:
使用 Flutter Hive 處理離線數(shù)據(jù)存儲(chǔ)入門
在這篇博客中,我們將探索在 Flutter 中使用 TypeAdapter 的 Hive 數(shù)據(jù)庫(kù)。我們還將創(chuàng)建一個(gè)只有一個(gè)頁(yè)面的簡(jiǎn)單應(yīng)用程序,用于顯示用戶列表、添加新用戶、更新現(xiàn)有用戶和刪除用戶。
如何使用Flutter Hive處理離線數(shù)據(jù)存儲(chǔ)?
第一步:依賴安裝
在我們使用 Hive 之前需要兩個(gè)依賴項(xiàng)。
配置單元和 hive_flutter
您需要將 Hive 和 hive_flutter 包添加到 pubspec.yaml 中,如下所示:
添加開(kāi)發(fā)依賴
第二步:初始化Hive數(shù)據(jù)庫(kù)
首先,我們必須在 flutter 應(yīng)用中調(diào)用 runApp 之前初始化 Hive。
void main() 異步{
WidgetsFlutterBinding.ensureInitialized();
// 使用應(yīng)用程序文件中的有效目錄初始化 Hive
等待 Hive.initFlutter();
runApp(const MyApp());}
initFlutter() 函數(shù)由Hive 提供。基本上,它使用getApplicationDocumentsDirectory 返回的路徑來(lái)初始化Hive
蜂巢中的盒子
下面介紹如何使用 Flutter Hive 處理離線數(shù)據(jù)存儲(chǔ)。
存儲(chǔ)在 Flutter Hive 中的數(shù)據(jù)被組織成盒子。盒子類似于 SQL 中的表,但它沒(méi)有結(jié)構(gòu),可以容納任何東西。正如我在介紹中提到的,Hive 對(duì)數(shù)據(jù)進(jìn)行加密。此外,加密的盒子可用于存儲(chǔ)敏感信息。
Hive 使用鍵值集存儲(chǔ)其數(shù)據(jù)。首先,你需要打開(kāi)你的盒子。
void main() 異步{
WidgetsFlutterBinding.ensureInitialized();// 使用應(yīng)用程序文件中的有效目錄初始化 Hive
等待 Hive.initFlutter();// 開(kāi)箱等待 Hive.openBox("用戶框");runApp(const MyApp());}
帶有 TypeAdapter 的模型類
我們的示例包含多個(gè)用戶,這些用戶具有姓名、愛(ài)好和描述等信息。
導(dǎo)入“包:hive/hive.dart”;“user_model.g.dart”部分;@HiveType(typeId: 0)類 UserModel 擴(kuò)展 HiveObject {@HiveField(0)
最終字符串名稱;
@HiveField(1)
最后的弦樂(lè)愛(ài)好;
@蜂巢場(chǎng)(2)
最終字符串描述;
用戶模型({需要this.name,需要這個(gè)愛(ài)好,
需要this.description,});}
首先,我們需要導(dǎo)入配置單元。為了生成類型適配器,添加一個(gè)名為 user_model.g.dart 的部分。TypeAdapter 不需要手動(dòng)構(gòu)造,因?yàn)槲覀兪褂玫氖?hive 生成器包。
它使用 hive_generator 包自動(dòng)為幾乎任何類構(gòu)建 TypeAdapter。
如您所見(jiàn),userModel 類使用多個(gè)字段進(jìn)行注釋。
@HiveType():用@HiveType()明確模型類,讓生成器意識(shí)到這應(yīng)該是一個(gè)TypeAdapter。
@HiveField(index):用這個(gè)字段注解類的字段及其對(duì)應(yīng)的索引是強(qiáng)制性的。
要構(gòu)建 TypeAdapter 類,請(qǐng)運(yùn)行以下命令。
這里文件名為user_model.dart,將添加data_model.g.dart文件,其中g(shù)代表generated。因此,user_model.g.dart 將是新生成的文件。
現(xiàn)在已經(jīng)成功構(gòu)建了 UserModelAdapter,是時(shí)候注冊(cè)它了。
為了實(shí)現(xiàn)這一點(diǎn),我們必須在調(diào)用 run app 函數(shù)之前編寫該適配器。
void main() 異步{
WidgetsFlutterBinding.ensureInitialized();// 使用應(yīng)用程序文件中的有效目錄初始化 Hive
等待 Hive.initFlutter();// 注冊(cè) Hive 適配器Hive.registerAdapter(用戶模型適配器());// 開(kāi)箱等待 Hive.openBox("用戶框");runApp(const MyApp());}
增刪改查操作
在 Hive 中創(chuàng)建數(shù)據(jù)
您可以使用對(duì) Hive 框的引用通過(guò)調(diào)用 add() 函數(shù)來(lái)添加數(shù)據(jù)。此方法接受鍵值對(duì)。
當(dāng)我們點(diǎn)擊浮動(dòng)按鈕時(shí),會(huì)打開(kāi)一個(gè)對(duì)話框,我們可以輸入姓名、愛(ài)好和描述。之后,我們將按下添加按鈕,數(shù)據(jù)就會(huì)出現(xiàn)。
Flutter Hive 中的ValuelistenableBuilder ()流也可以用來(lái)監(jiān)聽(tīng)盒子內(nèi)部發(fā)生的事情。
在 Hive 中檢索數(shù)據(jù)
可以使用 get() 方法讀取 Box 對(duì)象。要檢索它的值,您只需要提供密鑰,就像這樣
如果您使用的是自動(dòng)遞增值,則可以使用框?qū)ο蟮?getAt(index) 方法使用索引進(jìn)行讀取,如下所示
var userData = box.getAt(index);ValueListenableBuilder(
valueListenable: HiveDataStore.box.listenable(),
建設(shè)者:(上下文,盒子,小部件){
返回安全區(qū)域(
孩子:box.length > 0 ? ListView.builder(
收縮包裹:真,
itemCount: box.length,
itemBuilder: (BuildContext 上下文, int 索引) {
var userData = box.getAt(index);
返回容器(
填充:const EdgeInsets.all(10),
邊距:const EdgeInsets.all(10),
裝飾:BoxDecoration(顏色:Colors.grey.withOpacity(0.1),
邊框:Border.all(顏色:Colors.blue.shade900),
borderRadius: const BorderRadius.all(Radius.circular(10))),
孩子:行(
孩子們: [
擴(kuò)展(
彈性:1,
孩子:專欄(
crossAxisAlignment:CrossAxisAlignment.start,
孩子們: [
固有高度(
孩子:行(
孩子們: [
Text(userData.name, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w700),
),
VerticalDivider(顏色:Colors.blue.shade900,厚度:2,),
Text(userData.description, style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w500),
),
],
),
),
const SizedBox(高度:15),
RichText(text: TextSpan(text: 'Hobby: ', style: const TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w700),
孩子們:<TextSpan>[
TextSpan(text: userData.hobby, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
],
),
),
],
),
),
擴(kuò)展(
彈性:0,
孩子:行(
孩子們: [
墨水池(
onTap:(){
isUpdate.value = true;
nameEditingCtr.text = userData.name;
hobbyEditingCtr.text = userData.hobby;
descriptionEditingCtr.text = userData.description;
_showDialog(上下文,索引);
},
孩子:圖標(biāo)(Icons.edit,尺寸:30,顏色:Colors.blue.shade900,),
),
const SizedBox(寬度:10),
墨水池(
onTap: ()異步{
等待顯示對(duì)話框(
上下文:上下文,
構(gòu)建器:(上下文)=> AlertDialog(
title: Text('你確定要?jiǎng)h除 ${userData.name} 嗎?'),
動(dòng)作:<小工具>[
文本按鈕(
樣式:按鈕樣式(
背景顏色:MaterialStateProperty.all(Colors.blue.shade900),
海拔:MaterialStateProperty.all(3),
shadowColor: MaterialStateProperty.all(Colors.blue.shade900), //定義shadowColor
),
onPressed: () {dataStore.deleteUser(index: index);},
child: const Text('Yes', style: TextStyle(color: Colors.white),
),
),
文本按鈕(
風(fēng)格:ButtonStyle(背景顏色:MaterialStateProperty.all(Colors.blue.shade900),
海拔:MaterialStateProperty.all(3),
shadowColor: MaterialStateProperty.all(Colors.blue.shade900), //定義shadowColor
),
onPressed: () {Navigator.of(context, rootNavigator: true).pop(); },
孩子:常量文本('否',
樣式:TextStyle(顏色:Colors.white),
),
),
],
),
);
},
孩子:圖標(biāo)(圖標(biāo)。刪除,大?。?0,顏色:Colors.blue.shade900,))
],
)),
],
),
);
}):const Center(child: Text("未找到數(shù)據(jù)"),));
})
更新 Hive 中的數(shù)據(jù)
put() 方法可以更新你原來(lái)為一個(gè)鍵存儲(chǔ)的數(shù)據(jù)。這樣,新提供的值將在那個(gè)鍵上更新。
/// 更新用戶數(shù)據(jù)未來(lái)updateUser({required int index,required UserModel userModel}) async {
等待 box.putAt(index,userModel);}
這里我們使用了自動(dòng)遞增的值,你可以使用 box 對(duì)象的 putAt(index) 方法來(lái)使用索引進(jìn)行更新。
刪除 Hive 中的數(shù)據(jù)
為了刪除數(shù)據(jù),您可以將密鑰傳遞給 delete() 方法。
這里我們使用了自動(dòng)遞增的值,你可以使用box對(duì)象的deleteAt(index)方法來(lái)使用索引刪除。
懶人盒子
每次我們創(chuàng)建一個(gè)常規(guī)框時(shí),其內(nèi)容都會(huì)存儲(chǔ)在內(nèi)存中。因此性能很高。
當(dāng)您在 Box 中有大量數(shù)據(jù)并且不想將它們?nèi)考虞d到內(nèi)存中時(shí),LazyBox 是一種快速訪問(wèn)數(shù)據(jù)的好方法。
盒子壓縮
我們現(xiàn)在已經(jīng)完成了應(yīng)用程序的大部分編碼。是時(shí)候清理了:Hive 是一個(gè) append-only store??梢允謩?dòng)使用 .compact() 方法或者讓 Hive 為我們處理。
因此,我重寫了 dispose 方法以關(guān)閉 Openbox。
@覆蓋無(wú)效處置(){
//釋放空間
Hive.box('userBox').compact();
// 在關(guān)閉頁(yè)面之前關(guān)閉所有打開(kāi)的框。
蜂巢關(guān)閉();}
所有代碼都可以在這里找到:
https://github.com/mohitsolankee22/flutter_hive_db_blog
結(jié)論
我希望你已經(jīng)了解了 Hive DataBase 的基本結(jié)構(gòu)。毫無(wú)疑問(wèn),Hive 是一個(gè)優(yōu)秀、易用、快速、高效的數(shù)據(jù)庫(kù),尤其是它的速度非???,幾乎支持所有平臺(tái)。如果您在使用 Flutter Hive 處理離線數(shù)據(jù)存儲(chǔ)方面需要幫助,請(qǐng)隨時(shí)與我們聯(lián)系。
(言鼎科技)專做軟件開(kāi)發(fā),微信小程序,網(wǎng)站開(kāi)發(fā),軟件外包,手機(jī)APP開(kāi)發(fā),歡迎資訊!