サイトアイコン 【TechGrowUp】

Flutter開発入門27 FlutterでSQLiteを使ったデータベース操作:sqfliteパッケージを使ってCRUDを実装する方法

はじめに

 Flutterアプリでローカルにデータを保存する方法として、SQLiteデータベースが非常に人気です。特に、オフラインでもデータの永続化が必要なアプリ(タスク管理やメモアプリなど)では、SQLiteを使うことで効率的にデータを管理できます。本記事では、Flutterでsqfliteライブラリを使って、SQLiteデータベースを操作する方法を解説します。基本的なデータベースのセットアップから、データの挿入、取得、更新、削除まで、実例を通じてわかりやすく説明します。

sqfliteとは

 sqfliteは、FlutterでSQLiteデータベースを操作するための最も人気のあるパッケージです。このパッケージを使うと、モバイルアプリでローカルにデータを保存するためのシンプルなインターフェースを提供してくれます。

sqfliteの主な機能

これらの機能を使って、Flutterアプリで効率的にローカルデータを管理することができます。

ライブラリの準備

 まず、sqflitepathパッケージをpubspec.yamlファイルに追加します。pathパッケージはデータベースファイルのパスを取得するために使用されます。

dependencies:
  flutter:
    sdk: flutter
  sqflite: ^2.3.3+1
  path: ^1.9.0

 その後、以下のコマンドでパッケージをインストールします。

flutter pub get

パッケージのインポート

 Dartファイルでsqflitepathをインポートします。

import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

 これで、データベース操作の準備が整いました。

データベースのセットアップ

 まずは、データベースを作成し、テーブルを作成する基本的なセットアップから始めます。SQLiteデータベースは、モバイルデバイスのローカルストレージに保存されます。

データベースの初期化

 SQLiteデータベースを初期化するには、getDatabasesPath()openDatabase()を使います。

Future<Database> initializeDB() async {
  String path = join(await getDatabasesPath(), 'my_database.db');

  return openDatabase(
    path,
    onCreate: (database, version) async {
      await database.execute(
        "CREATE TABLE users(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)",
      );
    },
    version: 1,
  );
}

 このコードでは、usersテーブルを作成しています。このテーブルにはid(自動インクリメント)、name(テキスト)、およびage(整数)という3つのカラムを持っています。

データの挿入

 次に、データをテーブルに挿入する方法を見ていきます。

ユーザーデータの挿入

Future<void> insertUser(Database db, String name, int age) async {
  await db.insert(
    'users',
    {'name': name, 'age': age},
    conflictAlgorithm: ConflictAlgorithm.replace,
  );
}

 この関数では、usersテーブルに名前と年齢を挿入しています。ConflictAlgorithm.replaceは、同じ主キーのデータが既に存在する場合に、データを上書きするという意味です。

使い方例

Database db = await initializeDB();
await insertUser(db, 'John', 25);

データの取得

挿入されたデータを取得するには、query()メソッドを使います。

例: ユーザーリストの取得

Future<List<Map<String, dynamic>>> getUsers(Database db) async {
  return await db.query('users');
}

この関数では、usersテーブル内のすべてのユーザー情報を取得しています。

使い方例

List<Map<String, dynamic>> users = await getUsers(db);
for (var user in users) {
  print('User: ${user['name']}, Age: ${user['age']}');
}

データの更新

次に、データを更新する方法を見ていきます。update()メソッドを使って、特定のユーザーのデータを更新できます。

例: ユーザーデータの更新

Future<void> updateUser(Database db, int id, String name, int age) async {
  await db.update(
    'users',
    {'name': name, 'age': age},
    where: 'id = ?',
    whereArgs: [id],
  );
}

このコードでは、特定のidを持つユーザーの名前と年齢を更新しています。

使い方例

await updateUser(db, 1, 'John Doe', 30);

データの削除

最後に、データを削除する方法を見ていきます。delete()メソッドを使って特定のデータを削除できます。

例: ユーザーデータの削除

Future<void> deleteUser(Database db, int id) async {
  await db.delete(
    'users',
    where: 'id = ?',
    whereArgs: [id],
  );
}

このコードでは、指定したidを持つユーザーを削除しています。

使い方例

await deleteUser(db, 1);

完成したコードの例

 ここまで説明してきた各操作を組み合わせて、シンプルなCRUDアプリを実装することができます。

import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter SQLite Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: UserListScreen(),
    );
  }
}

class UserListScreen extends StatefulWidget {
  @override
  _UserListScreenState createState() => _UserListScreenState();
}

class _UserListScreenState extends State<UserListScreen> {
  late Database _db;
  List<Map<String, dynamic>> _users = [];

  @override
  void initState() {
    super.initState();
    _initializeDB();
  }

  Future<void> _initializeDB() async {
    _db = await initializeDB();
    _loadUsers();
  }

  Future<void> _loadUsers() async {
    _users = await getUsers(_db);
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Users'),
      ),
      body: ListView.builder(
        itemCount: _users.length,
        itemBuilder: (context, index) {
          var user = _users[index];
          return ListTile(
            title: Text(user['name']),
            subtitle: Text('Age: ${user['age']}'),
            trailing: IconButton(
              icon: Icon(Icons.delete),
              onPressed: () async {
                await deleteUser(_db, user['id']);
                _loadUsers();
              },
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          await insertUser(_db, 'New User', 20);
          _loadUsers();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

Future<Database> initializeDB() async {
  String path = join(await getDatabasesPath(), 'my_database.db');
  return openDatabase(
    path,
    onCreate: (database, version) async {
      await database.execute(
        "CREATE TABLE users(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)",
      );
    },
    version: 1,
  );
}

Future<void> insertUser(Database db, String name, int age) async {
  await db.insert(
    'users',
    {'name': name, 'age': age},
    conflictAlgorithm: ConflictAlgorithm.replace,
  );
}

Future<List<Map<String, dynamic>>> getUsers(Database db) async {
  return await db.query('users');
}

Future<void> deleteUser(Database db, int id) async {
  await db.delete(
    'users',
    where: 'id = ?',
    whereArgs: [id],
  );
}

 実行するとこんな感じになります。

まとめ

 Flutterでsqfliteライブラリを使うことで、SQLiteデータベースを簡単に操作できます。データの挿入、取得、更新、削除といった基本操作をマスターすれば、オフラインでも動作する強力なアプリを作成できます。今回の例を参考に、自分のアプリにデータベース機能を組み込んでみてください。

モバイルバージョンを終了