Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?

yanding 2023-06-03 456

幾乎每個(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如何處理離線數(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 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ǔ)?

如何使用Flutter Hive處理離線數(shù)據(jù)存儲(chǔ)?

第一步:依賴安裝

  • 在我們使用 Hive 之前需要兩個(gè)依賴項(xiàng)。

配置單元和 hive_flutter

  • 您需要將 Hive 和 hive_flutter 包添加到 pubspec.yaml 中,如下所示:

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
依賴項(xiàng):
撲:
      SDK: 顫動(dòng)
配置單元:^2.2.3
hive_flutter:^1.1.0

添加開(kāi)發(fā)依賴

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
dev_dependencies:
顫動(dòng)測(cè)試:
  SDK: 顫動(dòng)配置單元生成器:^1.1.3build_runner:^2.2.0

第二步:初始化Hive數(shù)據(jù)庫(kù)

首先,我們必須在 flutter 應(yīng)用中調(diào)用 runApp 之前初始化 Hive。

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
void main() 異步{
WidgetsFlutterBinding.ensureInitialized();
  // 使用應(yīng)用程序文件中的有效目錄初始化 Hive
等待 Hive.initFlutter();
runApp(const MyApp());}

initFlutter() 函數(shù)由Hive 提供。基本上,它使用getApplicationDocumentsDirectory 返回的路徑來(lái)初始化Hive

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?

您是否需要有關(guān)快速安全且沒(méi)有本機(jī)依賴項(xiàng)的本地?cái)?shù)據(jù)庫(kù)的幫助?

利用 Hive 的優(yōu)勢(shì) - 一種直接的鍵值數(shù)據(jù)庫(kù)解決方案在本地存儲(chǔ)數(shù)據(jù)。通過(guò) Sqflite 獲得即時(shí)優(yōu)勢(shì),因?yàn)?Hive 還允許您操作目標(biāo)設(shè)備上的數(shù)據(jù)。

雇用 Flutter 開(kāi)發(fā)人員

蜂巢中的盒子

下面介紹如何使用 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)你的盒子。

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
void main() 異步{
WidgetsFlutterBinding.ensureInitialized();// 使用應(yīng)用程序文件中的有效目錄初始化 Hive
等待 Hive.initFlutter();// 開(kāi)箱等待 Hive.openBox("用戶框");runApp(const MyApp());}

帶有 TypeAdapter 的模型類

我們的示例包含多個(gè)用戶,這些用戶具有姓名、愛(ài)好和描述等信息。

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
導(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)行以下命令。

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
flutter packages pub run build_runner 構(gòu)建

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?

這里文件名為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ù)之前編寫該適配器。

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
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ì)。

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
/// 添加新用戶未來(lái)addUser({required UserModel userModel}) async {
等待框。添加(用戶模型);}

當(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ā)生的事情。

您可能還喜歡閱讀:

Flutter 凍結(jié)示例:在 Flutter 應(yīng)用程序中學(xué)習(xí)凍結(jié)的速成班

在 Hive 中檢索數(shù)據(jù)

可以使用 get() 方法讀取 Box 對(duì)象。要檢索它的值,您只需要提供密鑰,就像這樣

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
var userHobby = box.get('愛(ài)好');

如果您使用的是自動(dòng)遞增值,則可以使用框?qū)ο蟮?getAt(index) 方法使用索引進(jìn)行讀取,如下所示

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
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è)鍵上更新。

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
/// 更新用戶數(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() 方法。

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
/// 刪除用戶未來(lái)deleteUser({required int index}) async {
等待 box.deleteAt(索引);}

這里我們使用了自動(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ù)的好方法。

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
var lazyBox = await Hive.openLazyBox('myLazyBox');var value = await lazyBox.get('lazyVal');

盒子壓縮

我們現(xiàn)在已經(jīng)完成了應(yīng)用程序的大部分編碼。是時(shí)候清理了:Hive 是一個(gè) append-only store??梢允謩?dòng)使用 .compact() 方法或者讓 Hive 為我們處理。

因此,我重寫了 dispose 方法以關(guān)閉 Openbox。

Flutter Hive如何處理離線數(shù)據(jù)存儲(chǔ)?
@覆蓋無(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ā),歡迎資訊!

The End