輕鬆了解 Isar NoSQL DB,用它來實作 Flutter 資料庫吧!
這篇寫於 2022 年。工具和 API 變化很快,部分步驟可能已經不適用。
很快能上手的資料庫套件
- 作者為了改善 Hive 而開發 Isar,也推薦未來使用 Isar
- 使用 NoSQL,容量小且速度快
- 擁有 Isar Inspector 檢查工具,類似 Flutter Devtool。提供視覺化呈現,輕鬆了解資料庫狀況,即時更新
- 存取操作預設都是非同步,避免堵塞 UI Thread。另外也有提供同步API,除非必要否則應盡力避免使用,不過因速度快同步也影響不大
- 可搭配 Isolate 使用,如果有另起 Isolate 進行資料處理,則可以進行同步操作,速度很快
- 透過 Generator 自動生成存取、操作所需的程式碼,節省重複工作
- 支援在 Mobile 和 Web 上運作,但個別有些許限制
Installation#
flutter pub add isar isar_flutter_libs
flutter pub add -d isar_generator build_runner
標註#
@collection#
代表集合,class上新增標記
@Collection()#
代表集合,可以透過參數進行細部設定
inheritance→ 是否儲存父類的屬性以及 mixins,預設 trueaccessor→ 自定義集合的入口。假如 class 為 User,通常是 users 為存取入口ignore→ 忽略,不要儲存指定欄位
@Name#
指定表和欄位名稱。建議集合跟屬性都要使用,為臨時改名做準備
@ignore#
不需要屬性在資料表建立欄位
@Enumerated#
枚舉,提供四種儲存類型
ordinal,byte,無法空值,較快但無法改變 enum 順序,否則會回傳錯誤資料ordinal32,short,無法空值,無法改變 enum 順序,否則會回傳錯誤資料name,String,預設方式value,String,custom String
支援的欄位型別#
一般資料欄位都是 nullable
ID→ 可以給予Isar.autoIncrement,不為空值的自動遞增。給予null 也是自動遞增boolintdoubleDateTimeStringList<bool>List<int>List<double>List<DateTime>List<String>
創建集合、資料表#
執行代碼生成,建立樣板代碼#
flutter pub run build_runner build
建立 Isar 實體,存取指定集合#
final isar = await Isar.open(
[UserSchema],
inspector: true,
);
- 設置要存取的 Collection,這邊添加自動生成的 Schema 類
- inspector 檢查工具,類似 Flutter DevTools,在 profile 和 release 模式無法使用
- 單一實體,每次
open()都會取得相同實體,對於在 Isolate 操作很有用
存取集合#
有提供兩種方式
//1.
isar.users
//2.
isar.collection<User>()
🐦 取得全部資料#
isar.users.where().findAll()
🐦 透過Id取得指定資料#
isar.users.get(1);
🐦 取得集合大小#
isar.users.getSize();
🐦 過濾資料#
Isar 提供很多常用的 API 函式,方便使用,不需要自己撰寫。例如:查詢名字裡有 Chen 的使用者
isar.users.filter().nameContains('Chen').findAll();
🐦 新增資料#
只要有修改資料庫的操作都需要在 transaction 裡處理,使用 writeTxn()
// Single
await isar.writeTxn(() => isar.users.put(user));
// Multiple
await isar.writeTxn(() => isar.users.putAll(users));
🐦 更新資料#
user.name = 'Jay'
await isar.writeTxn(() => isar.users.put(user));
🐦 刪除資料#
isar.writeTxn(() => isar.users.delete(1));
索引(Indexes)#
- 針對常用來查詢、過濾的欄位可以思考是否設置索引,Isar 會為索引欄位生成特定 API,使用上可以達到更省事更快速的性能
- 搭配
where()查詢 .anyXXX()生成函式,僅使用索引進行排序
可設置參數#
unique→ 唯一索引,此欄位無法出現相同內容replace→ 可替換索引,新 Object 可覆蓋caseSensitive→ 索引區分大小寫,預設為 true
索引種類#
IndexType.value→ 值索引,預設索引,最靈活但佔空間IndexType.hash→ 哈希索引,空間小但有些 API 不支援,例如:startsWith()IndexType.hashElements→ 哈希元素索引,進行散列,適用於List<String>
索引查詢#
// 使用 age 索引進行排序,只撈兩筆
isar.users.where().anyAge().limit(2).findAll();
複合索引(Composite indexes)#
- 也稱為 multiple-column indexes
- Isar 允許最多創建三個屬性的複合索引
- 適合想創建根據多個屬性排序的高效查詢
多項索引(Multi-entry indexes)#
列表中的每個元素都是索引
Isar.splitWords() 補充,可以完整切分字串,忽略空白以及標點符號
全文搜尋 Example,透過索引搜尋的效能很高,速度快
isar.users.where().descriptionWordsElementEqualTo('Chen').findAll();
Watchers 觀察者#
監聽指定集合和物件的更新,即時作出反應,執行對應操作
watchObject()#
- 監聽物件
- id → 集合索引
fireImmediately→ 設為 true,在一開始就將當前值新增到 Stream。預設為 false
Stream<User?> userUpdatedStream = isar.users.watchObject(1);
userUpdatedStream.listen((user) {
print('index 1 of user updated - $user');
});
watch()#
- 監聽集合
- 只要集合有更新就通知,並取得最新集合
Stream<List<User>> usersStream = isar.users.where().watch();
usersStream.listen((users) {
print('User collection updated - $users');
});
watchObjectLazy()#
- 懶監聽物件
- 不需要了解新內容,只需知道資料有更新
Stream<void> userUpdatedStream = isar.users.watchObjectLazy(2);
userUpdatedStream.listen(() {
print('index 2 of user updated.');
});
watch()#
- 懶監聽集合
Stream<void> usersUpdatedStream = isar.users.watchLazy();
usersUpdatedStream.listen((voidEvent) {
print('User collection updated.');
});
watch query#
- 監聽查詢
- 使用
build()建立 Query 物件,透過 Query 進行watch()監聽
注意:非必要請使用 lazy 操作,因為資料更新後的重新查詢效率很低
isar.users.filter().nameContains('Chen').build()
Isolate 多隔離操作#
- 如果需要存取大量資料可以考慮使用新的 Isolate 去處理,避免阻塞 Main isolate(UI thread)
- 可以在不同隔離存取相同 DB 實體。如果是新的 Isolate 就需要先執行
open()取得實體,因為每個隔離的內存是獨立的 - 簡單快速的方式是使用
compute(),更建議透過 Isolate pool 處理
Isar Inspector 工具#
App 運行後再 console 會看到本地網址,點擊後即可查看即時的資料庫狀態,擁有視覺化效果
Source Code#
其他文章#
- Flutter CICD 使用 Gitlab Runner 和 App Center 實作 part.1
- 使用 CodeMagic 和 Firebase 實現 Flutter CICD
- 輕鬆完成Flutter開發環境,最新版!
- 實作Flutter多變有趣的滾動效果CustomScrollView!
- 如何在Flutter使用 Makefile 節省你的時間?
- Easily understand StatefulWidget LifeCycle of Flutter
- “freezed” makes model class strong and easily
- 提高Flutter性能的小技巧!(一)
- 提高Flutter性能的小技巧!(二)
- 提高Flutter性能的小技巧!(三)
- What are Async and Isolates in Flutter?
- LoadBalancer is optimization for Isolates in Flutter
- Riverpod 輕鬆學,原來這麼好用!
- Riverpod 輕鬆學(二),一些進階用法!
關於我#
- GitHub: chyiiiiiiiiiiii
- Instagram: flutterluvr.yii
- Linkedin: yiichenhi
- Youtube: Yii
- Youtube: 一起饅頭(美食頻道)
- Email: ab20803@gmail.com
贊助#
謝謝你花費時間看完,非常感謝!
如果覺得文章不錯的話可以贊助,讓我有更多動力和熱情分享學習紀錄和生活!請我喝一杯咖啡吧~
最後#
希望有幫助到你/妳,歡迎追蹤我,方便瀏覽最新的文章~
本文原刊登於 Medium。