Open3

isarの使い方をメモ

JboyHashimotoJboyHashimoto

isarについてメモ

モデルを作る

user.dart
import 'package:isar/isar.dart';// 1. isarパッケージをインポート
part 'user.g.dart';// ファイル名.g.dartと書く


class User {
  Id id = Isar.autoIncrement; // id = nullでも自動インクリメントされます。

  String? name;

  int? age;
}

データを追加

add.dart
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:isar/isar.dart';
import 'package:isar_example/model/user.dart';

class AddPage extends StatefulWidget {
  final Isar isar;

  AddPage(this.isar);

  
  _AddPageState createState() => _AddPageState();
}

class _AddPageState extends State<AddPage> {
  final nameController = TextEditingController();
  final ageController = TextEditingController();
  // userStreamControllerはデータベースの中身を取得するための変数
  final userStreamController = StreamController<List<User>>();

  
  void dispose() {
    nameController.dispose();
    ageController.dispose();
    userStreamController.close();
    super.dispose();
  }
  // データベースの中身を取得するための関数
  void _updateUserStream() async {
    final users = await widget.isar.users.where().findAll();
    userStreamController.add(users);
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Isar Example11')),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          children: [
            TextField(
              controller: nameController,
              decoration: InputDecoration(labelText: 'Name'),
            ),
            TextField(
              controller: ageController,
              decoration: InputDecoration(labelText: 'Age'),
              keyboardType: TextInputType.number,
            ),
            ElevatedButton(
              child: Text('Save User'),
              onPressed: () async {
                // データベースに保存する処理
                final name = nameController.text;
                final age = int.tryParse(ageController.text);
                // nameとageが空でない場合に保存する
                if (name.isNotEmpty && age != null) {
                  final user = User()
                    ..name = name
                    ..age = age;
                  await widget.isar.writeTxn(() async {
                    await widget.isar.users.put(user);
                  });
                  _updateUserStream();
                }
              },
            ),
          ],
        ),
      ),
    );
  }
}

画面にデータを表示

list.dart
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:isar/isar.dart';
import 'package:isar_example/model/user.dart';
import 'package:isar_example/ui/add.dart';

class ListPage extends StatefulWidget {
  final Isar isar;

  const ListPage(this.isar, {super.key});

  
  _ListPageState createState() => _ListPageState();
}

class _ListPageState extends State<ListPage> {
  Future<List<User>>? futureUsers; // futureUsersはデータベースの中身を取得するための変数

  
  void initState() {
    super.initState();
    futureUsers = widget.isar.users.where().findAll();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(actions: [
        IconButton(
          icon: const Icon(Icons.add),
          onPressed: () {
            Navigator.of(context).push(
              MaterialPageRoute(
                builder: (context) => AddPage(widget.isar),
              ),
            );
          },
        ),
      ], title: const Text('Isar Example')),
      body: FutureBuilder<List<User>>(
        future: futureUsers,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(child: CircularProgressIndicator());
          } else if (snapshot.hasError) {
            return Center(child: Text('Error: ${snapshot.error}'));
          } else {
            final users = snapshot.data!;
            return ListView.builder(
              itemCount: users.length,
              itemBuilder: (context, index) {
                final user = users[index];
                return ListTile(
                  title: Text(user.name ?? "値が入ってません"),
                  subtitle: Text('Age: ${user.age ?? 0}'),
                );
              },
            );
          }
        },
      ),
    );
  }
}
JboyHashimotoJboyHashimoto

追加したパッケージの配置場所

pubspec.yaml
name: isar_example
description: A new Flutter project.
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1

environment:
  sdk: '>=3.0.0 <4.0.0'

# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
  flutter:
    sdk: flutter


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  isar: ^3.1.0+1
  isar_flutter_libs: ^3.1.0+1
  path_provider: ^2.0.15

dev_dependencies:
  flutter_test:
    sdk: flutter

  # The "flutter_lints" package below contains a set of recommended lints to
  # encourage good coding practices. The lint set provided by the package is
  # activated in the `analysis_options.yaml` file located at the root of your
  # package. See that file for information about deactivating specific lint
  # rules and activating additional ones.
  flutter_lints: ^2.0.0
  isar_generator: ^3.1.0+1 # isar_generatorはこの位置に配置する
  build_runner: ^2.4.4 # build_runnerはこの位置に配置する

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter packages.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/assets-and-images/#resolution-aware

  # For details regarding adding assets from package dependencies, see
  # https://flutter.dev/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.dev/custom-fonts/#from-packages

JboyHashimotoJboyHashimoto

エラーで詰まった

例外が発生しました
IsarError (IsarError: Write operations require an explicit transaction. Wrap your code in isar.writeTxn())

こちらが必要みたい
https://isar.dev/crud.html#reading-from-the-database

await isar.writeTxn(() async {
  final recipe = await isar.recipes.get(123)

  recipe.isFavorite = false;
  await isar.recipes.put(recipe); // perform update operations

  await isar.recipes.delete(123); // or delete operations
});