Flutter

FlutterでDriftデータベースを使用する初期設定方法

多数のデータを使うにあたって便利なのがデータベース。
Firebaseだとアカウントの制御だったりすることも大変、ローカルで保存できれば良いのであればSqliteなどが手軽で便利です。

Sqliteを簡単に扱えるためのパッケージも複数ありますが、「Drift」がその代表となります。
こちらのページではそんなDriftパッケージを使用してSqliteを使用していくために、Driftの初期設定方法について解説していきます。

アプリ開発のデータ管理にDriftを使ってみたい時に、参考にしてみて下さい。

最初に簡単に必要なステップを書いておくとこのようになります。

  • Driftを使用するのに必要なパッケージを追加する
  • Drift専用のディレクトリを用意する
  • Driftのテーブル定義を書く
  • Driftを操作するclassを作成する
  • コードジェネレーターで必要なファイルを作成する
  • 使用する場所でdatabase用classを呼び出す

公式ドキュメント見れば自分でわかるよ!って場合は公式サイトを見て実際に使用してみて下さい。

では具体的にみていきましょう!

Driftを使用するのに必要なパッケージを追加する

flutter pub add drift sqlite3_flutter_libs path_provider path
flutter pub add drift_dev build_runner --dev 

上記二つをFlutterのルートディレクトリで実行します。

これでDriftデータベースを使用するための準備が完了です。

Drift専用のディレクトリを用意する

ここは人によって実装方法が違うと思うのですが、個人的に使用する場合はlibディレクトリ配下にDrift専用のディレクトリを用意しています。

DriftはCode Generatorなどでも多数のファイルが作成されるため、分けておくことで管理しやすいようにしています。
そこは個人によって適宜変更してみて下さい。

Driftのテーブル定義を書く

まず最初にテーブル定義を書きます。
ここで定義した型でSqliteのテーブルが作成されるようになります。

テーブル名は「複数形」で書くのがルールになっています。

import 'package:drift/drift.dart';

class Users extends Table {
  IntColumn      get id       => integer().autoIncrement()();
  TextColumn     get name     => text().withLength(min: 2, max: 30)();
  TextColumn     get hurigana => text()();
  DateTimeColumn get birthday => dateTime().nullable()();
  IntColumn      get group    => integer().nullable()();
}

テーブル定義を書いていきます。

Driftの型
文字列TextColumn
数字IntColumn
日付時刻DateTimeColumn

まずテーブルのフィールドの型で定番だけを書くとこのような型定義になります。

設定内容メソッド
自動増分.autoIncrement()
Nullを許容.nullable()
規定値.withDefault(const Constant(false))
文字列長.withLength(min: 2, max: 30)

テーブルへの制約も簡単なところは上記になります。

実際にはもっと色々と設定できることは多いので、ここではそこまで解説しません。
主キー、インデックスの追加、ユニーク制約など、より詳しく知りたい場合はDrift公式を見てみて下さい。

Driftを操作するclassを作成する

実際に定義したテーブルの型情報をもとにテーブルを作成するマイグレーションや、初期値を自動で入力するシーディングをしてくれるクラスを作成していきます。
※ファイル名はここでは「database.dart」します

import 'dart:io';

import 'package:drift/drift.dart';
import 'package:sampleapp/drift/Tables/users.dart';
import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;

part 'database.g.dart';

@DriftDatabase(tables: [Users])
class AppDatabase extends _$AppDatabase {
  AppDatabase() : super(_openConnection());

  @override
  int get schemaVersion => 1;
  @override
  MigrationStrategy get migration {
    return MigrationStrategy(
      onCreate: (Migrator m) async {
        await m.createAll();
      },
    );
  }
}

LazyDatabase _openConnection() {
  return LazyDatabase(() async {
    final dbFolder = await getApplicationDocumentsDirectory();
    final file = File(p.join(dbFolder.path, 'db.sqlite'));
    return NativeDatabase.createInBackground(file);
  });
}

とりあえず上記の通りに書いてみて下さい。
この時点でVsCode上では以下のようにエラーが表示されていると思います。

この「part 'database.g.dart'」というのは、このファイルはdatabase.g.dartも一部であることを表しています。
まだ「database.g.dart」は作成されていないので、エラーが表示されています。

後で解消されるので、ここでは置いておきます。

importとpartについて

importと似ているのですが、少し役割が違います。
違いとしてはこのようになります。

  • import:publicのみ読み込む
  • part:public,private両方を読み込む

class名と、継承元の名前はルールに従ってつける

12行目に書かれている「class AppDatabase extends _$AppDatabase」という部分についての話になります。

class名は自由につけてもらって良いのですが、次にある「extends _$AppDatabase」の部分の「_$」の後の部分に同じclass名をつけておく必要があるのでご注意ください。

テーブルを追加したらtablesに追加する

11行目に「tables」というぷ引数があると思います。
Driftで使用するテーブルclassの配列になります。

今回はUsersだけですが、今後新規でテーブルを増やすときはここに追加していきます。

_openConnection

このメソッドを使用することでSqliteを作成したり、データーベースとの接続を行うためのメソッドとなっています。

final file = File(p.join(dbFolder.path, 'db.sqlite'));
// db.sqlite の部分がデータベースファイル名になるので、好みで変更して下さい

schemaVersion

現在のバージョンを指定しています。

テーブルを増やしたり、値を強制的に追加したりするときにこのバージョン番号をあげていくことで、新規ユーザーと、アップデートするユーザーに対して必要な処理をできるようになってます。

migration

18行目にあるmigrationはデータベースに対しての処理を書く場所になります。

今回の例では「onCreate」で書いているのですが、こちらはデータベースが作成されるときに実行される処理です。
12行目の「m.createAll()」でtablesで指定したテーブル全てを作成するように書いています。

今後アップデートしたときにはonUpdateに書くことで、アップデートした時に実行する処理を書く形になります。

それ以外にも設定できる項目はあるのですが、こちらのページではあくまでDriftの初期設定なので省略させてもらいます。

コードジェネレーターで必要なファイルを作成する

ここまででclassを作成したらコードジェネレーターを使用して、関連ファイルを作成します。

プロジェクトのルートフォルダで以下を実行します。

dart run build_runner build 

毎回このコマンドを覚えるが大変という場合は、VSCodeであれば「F1」を押して「Build Runner:Build」をクリックでも実行可能です。

しばらく待つと作成が完了します。

すると先ほど作成した「database.dart」のあるフォルダに「database.g.dart」というファイルが作成され、database.dartでエラー表示されていた部分のエラーが解消されているかと思います。

使用する場所でdatabase用classを呼び出す

あとは実際にDriftパッケージを使用してSqliteを呼び出したいときに先ほど作成したclassを呼び出してあげるとdatabaseを使用できます。

例えばアプリを起動した時、データベースからデータ取得して処理するという場合はmain.dartにこのように書きます。

void main() async {
  // runApp()の前にdatabaseを初期化します。
  WidgetsFlutterBinding.ensureInitialized();
  final database = AppDatabase();
  // ここにdatbaseを使用したコードを記述します。
  runApp(const MyApp());
}

具体的にdatabaseを使用した内容はこちらのページでは書きませんが、ここまででDriftを実際に使用するまでの準備完了です。

FlutterでDriftを使用するための初期設定 最後に

ここまでお読みいただきありがとうございました。

Flutterを使い始めてすぐという場合には、少し難しいところがあったかもしれません。
初期設定以降にはもっと複雑だったりするところも多いです汗

とはいえ、Driftは簡単にデータベースを使えるので覚えてしまえば非常に便利です。

この解説を読んでわかりにくい部分や、もっと詳しく知りたい部分があったらぜひコメントください!

-Flutter
-, ,