CRUD操作

コレクションを定義したら、それを操作する方法を学びましょう。

Isarを開く

何をするにしても、まずはIsarのインスタンスが必要です。各インスタンスには、データベースファイルを格納することができる書き込み権限のあるディレクトリが必要になります。ディレクトリを指定しない場合、Isarは現在のプラットフォームに適したデフォルトのディレクトリを見つけます。

Isarインスタンスで使用したいすべてのスキーマを指定します。複数のインスタンスを開いている場合でも、それぞれのインスタンスに同じスキーマを与える必要があります。

final dir = await getApplicationDocumentsDirectory();
final isar = await Isar.openAsync(
  [ContactSchema],
  directory: dir.path,
);

加えて、デフォルト設定を使用するか、もしくは以下のいくつかのパラメータを指定することができます:

ConfigDescription
name複数のインスタンスを別々の名前で開きます。デフォルトでは、"default" が使用されます。
directoryこのインスタンスの保存場所です。相対パスまたは絶対パスを渡すことができます。デフォルトでは、iOS では NSDocumentDirectory が、Android では getDataDirectory が使用されます。Webにおいては必要ありません。
relaxedDurability書き込み性能を向上させるために耐久性保証を緩和します。 アプリケーションのクラッシュではなく、システムクラッシュの場合、最後にコミットしたトランザクションが失われる可能性があります。破損する可能性はありません。
compactOnLaunchインスタンスを開く際にデータベースの圧縮を行うかどうかを確認するための条件です。
inspectorデバッグビルドでインスペクターを有効にします。プロファイルとリリースビルドでは、このオプションは無視されます。

既にインスタンスが開かれている場合に Isar.open() を呼び出すと、指定したパラメータに関係なく既存のインスタンスを取得します。これはIsarをアイソレートで使用する場合に便利です。

ヒント

すべてのプラットフォームで有効なパスを取得するために、path_provideropen in new windowパッケージの使用を検討してください。

データベースファイルの保存場所は directory/name.isar です。

データベースからの読み込み

IsarCollection インスタンスを使用して、Isar で指定した型のオブジェクトを検索したり、照会したり、新規に作成したりすることができます。

これ以降のサンプルコードでは、コレクション Recipe が以下のように定義されていると仮定した上で述べて行きます。

@collection
class Recipe {
  late int id;

  String? name;

  DateTime? lastCooked;

  bool? isFavorite;
}

コレクションの取得

すべてのコレクションは、Isarインスタンスに格納されています。あなたはrecipesコレクションを次のように取得できます:

final recipes = isar.recipes;

idを用いたオブジェクトの取得

まだコレクションにデータはありませんが、あるものと仮定して、 123 という ID の架空のオブジェクトを取得してみましょう。

final recipe = await isar.recipes.getAsync(123);

getAsync() はオブジェクトを含む Future を返しますが、オブジェクトが存在しない場合は null を返します。 Isar のすべての操作はデフォルトでは非同期ですが、ほとんどの操作には同期処理も対応しています:

final recipe = recipes.get(123);

警告

UIアイソレートでは、非同期バージョンのメソッドをデフォルトで使用する必要があります。ちなみに、Isarは非常に高速なので、多くの場合において同期バージョンを使用しても問題ありません。

複数のオブジェクトを一度に取得したい場合は、 getAll() または getAllSync() を使用してください:

final recipe = await isar.recipes.getAll([1, 2]);

オブジェクトのクエリ

IDでオブジェクトを取得する代わりに、 .where().filter() を使って特定の条件に一致するオブジェクトのリストを取得することもできます:

final allRecipes = await isar.recipes.where().findAll();

final favouires = await isar.recipes.filter()
  .isFavoriteEqualTo(true)
  .findAll();

➡️ 詳しくはこちら: クエリ

データベースの書き換え

いよいよコレクションを書き換えるときがやってきました! オブジェクトを作成、更新、削除するには、それぞれの操作をWriteトランザクション内でラップして使用します:

await isar.writeAsync((isar) async {
  final recipe = await isar.recipes.getAsync(123)

  recipe.isFavorite = false;
  await isar.recipes.put(recipe); // 更新操作の実行

  await isar.recipes.delete(123); // 削除操作の実行
});

➡️ 詳しくはこちら: トランザクション

オブジェクトの挿入

Isar でオブジェクトを永続化するには、コレクションにオブジェクトを挿入(put)します。

Isar の put() メソッドは、そのオブジェクトが既にコレクションに存在するかどうかに応じて、オブジェクトの挿入もしくは更新を行います。

この時、id フィールドが null または Isar.autoIncrement の場合、Isar はオートインクリメントの id を使用します。

final pancakes = Recipe()
  ..id = isar.recipes.autoIncrement()
  ..name = 'Pancakes'
  ..lastCooked = DateTime.now()
  ..isFavorite = true;

await isar.writeAsync((isar) async {
  await isar.recipes.put(pancakes);
})

Isarは id フィールドがfinalでは無い場合、オブジェクトに自動的にidを割り当てます。

複数のオブジェクトを一度に挿入することも簡単です。

await isar.writeAsync((isar) async {
  await isar.recipes.putAll([pancakes, pizza]);
})

オブジェクトの更新

作成と更新の両方は collection.put(object) で行います。id が null (または存在しない) 場合はオブジェクトは挿入され、そうでない時は更新されます。

つまり、pancakesをunfavoriteにしたい場合は、以下のようになります:

await isar.writeAsync((isar) async {
  pancakes.isFavorite = false;
  await isar.recipes.put(recipe);
});

オブジェクトの削除

オブジェクトを削除したい場合は、collection.delete(id)を使用してください. delete メソッドは、指定された id を持つオブジェクトを見つけて、それを削除したかどうかを返します。例えば、id が 123 のオブジェクトを削除したい場合、以下のようになります。

await isar.writeAsync((isar) async {
  final success = await isar.recipes.delete(123);
  print('Recipe deleted: $success');
});

getやputと同様に、削除されたオブジェクトの数を返す一括削除命令も存在します:

await isar.writeAsync((isar) async {
  final count = await isar.recipes.deleteAll([1, 2, 3]);
  print('We deleted $count recipes');
});

削除したいオブジェクトのidが分からない場合は、クエリを使用することができます:

await isar.writeAsync((isar) async {
  final count = await isar.recipes.filter()
    .isFavoriteEqualTo(false)
    .deleteAll();
  print('We deleted $count recipes');
});