Flutter 向け Crazy fast な データベース Isar が便利
Flutter アプリにおいて、端末ローカル内にデータを永続化するための方法はいくつかあります。
Awarefy ではこれまで、SharedPreference または Hive を利用していたのですが、今回アプリに「タグ」のインクリメンタルサーチを実装するための機構を検討していたところ、Isar というパッケージを見つけ採用することにしました。
使い方
スキーマの定義
まずはじめにスキーマを定義します。
import 'package:isar/isar.dart';
part 'tag.g.dart';
class Tag {
Tag({
required this.uuid,
required this.label,
required this.createdAt,
required this.updatedAt,
});
final Id? id;
// original id of an entity
(unique: true, replace: true, type: IndexType.value)
final String uuid;
(type: IndexType.value)
final String label;
final DateTime createdAt;
final DateTime updatedAt;
}
コード生成
スキーマの定義をしたら、コード生成を行います。
flutter pub run build_runner build
データベース操作処理の実装
データベースの操作処理を実装します。
Future<List<domain.Tag>> findByLabel(String text) async {
final isar = await getDb();
final rows = await isar.tags
.filter()
.labelContains(text, caseSensitive: false)
.findAll();
// <<省略 ドメインオブジェクトへの変換処理>>
return tags;
}
特に気に入った点は、コード生成していることにより、スキーマにマッチしたメソッド、上記の例で言う labelContains()
あらかじめ準備されており、Type Safe な開発体験を得られることです。
タグを uuid の値に基づき削除したい場合は次のようになります。
Future<void> remove(String id) async {
final isar = await getDb();
await isar.writeTxn(() async {
await isar.tags.deleteByUuid(id);
});
}
deleteByUuid()
というメソッドが利用できます。ちなみに isar.tags
の tags
も自動生成により作成された部分で、直感的かつ Type Safe にコレクションを操作できます。
Tips
- Id は 大人しく Nullable にしておく。
Isar では プライマリキーとして Id型 のフィールド id
が採用されます。
class Tag {
Tag({
}) : id = Isar.autoIncrement;
final Id id;
とかやりたくなるのですが、データ取得したときの挙動が期待通りにならなかったので nullable にして null のママにしておいたほうがよさそうです(詳細未検証)。
- プライマリキーを任意の型にしたい場合
公式ドキュメントの次のページに記載があるのですが、
例えば文字列の UUID を持つフィールドの値から int の Hash を生成する関数を用意して Id get isarId => fastHash(id!);
のように利用する方法があるようです。
個人的な通常のDB設計でプライマリキーを AutoIncrement な値にすることはせず UUID などを採用することを好みますが、キャッシュなどのある種使い捨てのデータベースととらえる場合は何でもいいかなと思うので、公式推奨っぽい Id?
型を利用することにしました。
- 複合インデックス
Composite indexes の項に複合インデックスについての解説があります。
Foo {
String? bar;
(
unique: true,
composite: [CompositeIndex('bar', type: IndexType.hash)],
)
String? baz;
}
みたいな定義をしておくと、
final foo = await isar.foo.getByBazuBar();
のように getByBazuBar()
メソッドが(コード生成すると)生えてきます。便利。
付録
Awarefy でも利用したことのある、その他のローカルストレージ/データベースパッケージを掲載しておきます。
手軽な Key Value Store として利用できる SharedPreference
端末ローカルとはいえセンシティブな情報を管理したい場合に利用できる SecureStorage
一定の複雑さの構造データを高速に扱いたい場合の(これまでの)定番パッケージ Hive

AI メンタルパートナー アウェアファイを開発する、株式会社Awarefy の技術ブログ Zenn 支社です。 技術ブログ(公式) awarefy.dev
Discussion