[基礎知識]Windowsプラットフォーム環境向け/sqflite_common_ffiパッケージによるSQLiteの利用手順

flutter開発でsqflite系パッケージでWindowsプラットフォーム環境向けにSQLite操作を実装する場合の手順です。

(Androidプラットフォーム環境向けの場合はこちら(以下の別記事「[基礎知識]Androidプラットフォーム環境向け/sqfliteパッケージによるSQLiteの利用手順」)をご覧下さい。

今回のWindowsプラットフォーム環境向けの場合は以降の通りです。

1.Flutterプロジェクト作成

(1) ターミナルを開き、以下のコマンドを実行して新しいプロジェクトを作成します。

flutter create sqlite_example

(2) プロジェクトフォルダに移動します。

cd sqlite_example

2 必要な パッケージの追加

Windowsプラットフォーム環境で、SQLiteを使用するために必要なパッケージ(次の2つ)を追加します。

  • sqflite_common_ffi
  • path

(1) プロジェクトフォルダで次のコマンドによりsqflite_common_ffiパッケージとpathパッケージ(の依存関係)を追加します。

flutter pub add sqflite_common_ffi
flutter pub add path

(2) pubspec.yamlファイルを開き、上記パッケージ(の依存関係)が追加されていることを確認します。

pubspec.yaml:
dependencies:
  flutter:
    sdk: flutter

  path: ^1.9.0
  sqflite_common_ffi: ^2.3.3

(3) ターミナルで以下のコマンドを実行してパッケージをインストール(反映)します。

flutter pub get

(4) ※但しSQLite操作と関係なく元々必要なパッケージ(これは処理内容によりますが)は上記説明に含めていません。
 (例)material.dart、foundation.dart、等

3.SQLiteデータベースの設定と使用

以下は、SQLiteデータベースを設定し、使用するためのサンプルコードです。

3.1 データベースヘルパークラスの作成

まず、データベース操作を行うためのヘルパークラスを作成します。

(1) lib\database_helper.dartファイルを作成します。

database_helper.dart:
// SQLite操作(Windows環境専用)データヘルパー:

import 'package:path/path.dart';  // ファイルパスを操作するためのパッケージ
import 'package:sqflite_common_ffi/sqflite_ffi.dart'; // (Windows環境用)FFI

// DB_HELPERクラス
class DatabaseHelper {
  // シングルトンインスタンス保持変数
  static final DatabaseHelper _instance = DatabaseHelper._internal();
  // ファクトリコンストラクタ : クラスの新しいインスタンスを返すのではなく、既存のインスタンスを返すことができます。
  factory DatabaseHelper() => _instance;
  // プライベートコンストラクタ : このクラスの外部からインスタンスを作成できないようにするためのものです。
  DatabaseHelper._internal();
  // DBインスタンス : データベースの接続を保持する変数です。
  static Database? _database;

  // データベースのインスタンスを取得(存在しない場合は初期化)
  // ※database: getter定義プロパティ
  //   get: これを定義する為のgetterメソッド
  Future<Database> get database async {
    if (_database != null) return _database!;
    _database = await _initDatabase();
    return _database!;
  }

  // データベースを初期化するメソッド
  Future<Database> _initDatabase() async {
    String path = '';

    var databasePath = await getDatabasesPath();
    path = join(databasePath, 'SQLiteExampleForWindows.db');
    // データベースを開く(存在しない場合は作成)
    return await openDatabase(
      path,
      version: 1,
      onCreate: _onCreate, // データベースが作成された時に実行されるメソッド
    );
  }

  // データベーステーブルを作成するメソッド
  Future _onCreate(Database db, int version) async {
    await db.execute(
      '''
      CREATE TABLE items (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT
      )
      '''
    );
  }

  // アイテムを取得するメソッド
  Future<List<Map<String, dynamic>>> getItems() async {
    final db = await database;  // データベースのインスタンスを取得
    return await db.query('items'); // 'items' テーブルからすべてのデータを取得
  }

  // アイテムを追加するメソッド
  Future<void> insertItem(Map<String, dynamic> item) async {
    final db = await database;  // データベースのインスタンスを取得
    await db.insert('items', item, conflictAlgorithm: ConflictAlgorithm.replace);
  }

  // アイテムを削除するメソッド
  Future<void> deleteItem(int id) async {
    final db = await database;
    await db.delete('items', where: 'id = ?', whereArgs: [id]);
  }

  // アイテムを更新するメソッド
  Future<void> updateItem(Map<String, dynamic> item) async {
    final db = await database;
    await db.update('items', item, where: 'id = ?', whereArgs: [item['id']]);
  }

}

3.2 本処理の作成

次に本処理を作成してSQLiteデータベースを利用します。

(1) lib\main.dartファイルを開き、以下の様に書き換えます。

main.dart:
// SQLite操作(Windows環境専用)メインプログラム:

import 'package:flutter/material.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart'; // (Windows環境用)FFI

// データベースヘルパーのインポート
import 'database_helper.dart'; 

// DB環境初期化関数(Platform別)
void initDatabase() {
  // Windows対象時(ffi初期化が必要)
  sqfliteFfiInit();
  databaseFactory = databaseFactoryFfi;
}

Future<void> main() async {
  // DB環境初期化関数(Platform別)呼出
  initDatabase();

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SQLite Example for Windows plattform',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  MyHomePageState createState() => MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  // DB_HELPERのインスタンス
  final DatabaseHelper _databaseHelper = DatabaseHelper();
  // テキストフィールドのコントローラ
  final TextEditingController _controller = TextEditingController();
  // 取得したアイテムを格納するリスト
  List<Map<String, dynamic>> _items = [];

  @override
  void initState() {
    super.initState();
    _loadItems(); // アイテムをロード
  }

  // データベースからアイテムを読み込むメソッド
  Future<void> _loadItems() async {
    final items = await _databaseHelper.getItems();
    setState(() {
      _items = items;
    });
  }

  // アイテムを追加するメソッド
  Future<void> _addItem(String name) async {
    await _databaseHelper.insertItem({'name': name});
    _controller.clear(); // テキストフィールドをクリア
    _loadItems(); // アイテムを再読み込み
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('SQLite Example for Windows plattform'),
      ),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextField(
              controller: _controller,
              decoration: InputDecoration(
                labelText: 'Item Name',
                suffixIcon: IconButton(
                  icon: const Icon(Icons.add),
                  onPressed: () {
                    if (_controller.text.isNotEmpty) {
                      _addItem(_controller.text); // アイテムを追加
                    }
                  },
                ),
              ),
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: _items.length, // アイテムの数
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(_items[index]['name']), // アイテムの名前を表示
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

4. 起動・動作確認

(1) Windows向けデバッグモード実行

今回は必ずwindowsモードで実行して下さい。
(※対象プラットフォームが、web/androidの場合の利用手順は別途)

> flutter run -d windows

(2) 起動・動作の確認

再起動後も上記データは読込・表示されました。

(3) SQLiteデータベース確認

sqflite_common_ffiパッケージ利用時のSQLiteデータベースは以下のフォルダに作成されます。

flutterプロジェクト\.dart_tool\sqflite_common_ffi\databases

(4) SQLite3によるデータベース確認

>cd .dart_tool\sqflite_common_ffi\databases

>sqlite3
sqlite> .open SQLiteExampleForWindows.db
sqlite> .tables
items
sqlite> select * from items;
1|富士山

SQLite3インタフェースからも確認できました。

Windowsプラットフォーム環境向け/sqflite_common_ffiパッケージによるSQLiteの利用手順は以上です。

コメントを残す