Help us understand the problem. What is going on with this article?

【Flutter】sqfliteでローカルDBを実装する

環境

Flutter 1.7.8+hotfix.4 
• channel stable 
• https://github.com/flutter/flutter.git
Framework 
• revision 20e59316b8 (5 weeks ago) 
• 2019-07-18 20:04:33 -0700
Engine 
• revision fee001c93f
Tools
 • Dart 2.4.0

導入

私の環境ではflutter_testpath: ^1.6.2に依存しているため、2019/08/22現在の最新版(1.6.4)ではなく1.6.2を指定しています。

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter

  sqflite: ^1.1.6+3
  # flutter_testが1.6.2に依存しているため
  path: ^1.6.2

実装

下記の方針で実装しました。

  • データベースはシングルトンにする。
  • 今後複数のデータベースを実装することを想定。

(記載のコードはimport文を省略しています。)

database_provider.dart
/// データベース毎にこのクラスを継承したProviderを実装する
abstract class DatabaseProvider {
  Database _instance;

  String get databaseName;

  String get tableName;

  Future<Database> get database async {
    if (_instance == null) {
      _instance = await openDatabase(
        join(
          await getDatabasesPath(),
          databaseName,
        ),
        onCreate: createDatabase,
        version: 1,
      );
    }
    return _instance;
  }

  /// DBがpathに存在しなかった場合に onCreateメソッドが呼ばれます。(https://iganin.hatenablog.com/entry/2019/01/09/010804 より)
  createDatabase(Database db, int version);
}
search_history_database_provider.dart
class SearchHistoryDatabaseProvider extends DatabaseProvider {
  @override
  String get databaseName => "search_history_database.db";

  @override
  String get tableName => "histories";

  @override
  createDatabase(Database db, int version) => db.execute(
        """
          CREATE TABLE $tableName(
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            searchWord TEXT,
            searchCondition TEXT
          )
        """,
      );
}

書き込みするデータはクラスとして定義しました。
書き込みにはMap<String, dynamic>型のデータが必要なので、今回はJsonSerializableを使ってMapへの変換処理を自動生成しました。

search_history.dart
@JsonSerializable()
class SearchHistory {
  SearchHistory({
    @required this.searchWord,
    @required this.searchCondition,
  });

  final String searchWord;
  final String searchCondition;

  Map<String, dynamic> toMap() => _$SearchHistoryToJson(this);
}

任意の箇所でDatabaseProviderを呼び出して書き込みします。

  Future<int> addHistory(SearchHistory history) async {
    final SearchHistoryDatabaseProvider provider = SearchHistoryDatabaseProvider();
    final Database database = await provider.database;
    return await database.insert(provider.tableName, history.toMap());
  }

確認

AndroidStudio3.0.1からはDevice File Explorerタブから端末内フォルダの確認が可能です。
data/data/<package_name>/databasesの中にデータベースのファイルが生成されていれば成功です。
image.png

参考リンク

Persist data with SQLite
FlutterでローカルDBを扱う方法
インストール手順からデータベースインスタンスの生成方法、基本的なDB操作の参考にしました。

Dev tips
Android端末内にデータベースが作成できているか確認する方法の参考にしました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした