Flutter で SQFlite を使ってデータベースクエリを実行する方法
Flutter で SQFlite を使ってデータベースクエリを実行する方法
Flutter で SQLite を使用するには、sqflite
パッケージをインストールする必要があります。このパッケージは、Flutter アプリケーションで SQLite データベースを作成、管理、クエリするための便利な API を提供します。
データベースの作成と接続
まず、データベースファイルを作成して接続する必要があります。以下のコードは、my_database.db
という名前のデータベースファイルを作成し、データベースへの接続オブジェクトを作成する方法を示しています。
import 'package:sqflite/sqflite.dart';
Future<Database> openDatabase() async {
// データベースファイルのパスを取得
final databasesPath = await getDatabasesPath();
// データベースファイルのパスとデータベース名を使ってデータベースを開く
final database = await openDatabase(
join(databasesPath, 'my_database.db'),
onCreate: (db, version) {
// データベースが初めて作成されたときに実行される onCreate コールバック関数
// この中で、テーブルの作成などの初期化処理を行う
db.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)');
},
version: 1,
);
return database;
}
データの挿入
データベースにデータ挿入するには、insert
メソッドを使用します。以下のコードは、users
テーブルに新しいレコードを挿入する方法を示しています。
Future<void> insertUser(User user) async {
// データベースへの接続を取得
final db = await openDatabase();
// データを挿入する
await db.insert(
'users',
{
'name': user.name,
'age': user.age,
},
);
}
Future<List<User>> getUsers() async {
// データベースへの接続を取得
final db = await openDatabase();
// クエリを実行して結果を取得
final List<Map<String, dynamic>> maps = await db.query('users');
// 結果を User オブジェクトのリストに変換
return List.generate(maps.length, (i) {
return User(
id: maps[i]['id'],
name: maps[i]['name'],
age: maps[i]['age'],
);
});
}
Future<void> updateUser(User user) async {
// データベースへの接続を取得
final db = await openDatabase();
// データを更新
await db.update(
'users',
{
'name': user.name,
'age': user.age,
},
where: 'id = ?',
whereArgs: [user.id],
);
}
Future<void> deleteUser(int id) async {
// データベースへの接続を取得
final db = await openDatabase();
// データを削除
await db.delete(
'users',
where: 'id = ?',
whereArgs: [id],
);
}
補足
- 上記のコードはあくまで例であり、実際のアプリケーションでは状況に合わせて変更する必要があります。
- エラー処理やトランザクション処理などの詳細については、
sqflite
ドキュメントを参照してください。
Flutter で SQFlite を使ったサンプルコード
main.dart
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
void main() async {
// データベースを開く
final database = await openDatabase('notes.db');
// アプリを実行
runApp(MyApp(database: database));
}
class MyApp extends StatelessWidget {
final Database database;
const MyApp({Key? key, required this.database}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(database: database),
);
}
}
class MyHomePage extends StatefulWidget {
final Database database;
const MyHomePage({Key? key, required this.database}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final TextEditingController _titleController = TextEditingController();
final TextEditingController _contentController = TextEditingController();
List<Note> _notes = [];
@override
void initState() {
super.initState();
// データベースからメモを取得
_getNotes();
}
Future<void> _getNotes() async {
final List<Map<String, dynamic>> maps = await widget.database.query('notes');
_notes = List.generate(maps.length, (i) {
return Note(
id: maps[i]['id'],
title: maps[i]['title'],
content: maps[i]['content'],
);
});
setState(() {});
}
Future<void> _addNote() async {
final title = _titleController.text;
final content = _contentController.text;
// データベースにメモを挿入
await widget.database.insert(
'notes',
{
'title': title,
'content': content,
},
);
// メモの一覧を更新
_getNotes();
// 入力欄をクリア
_titleController.clear();
_contentController.clear();
}
Future<void> _deleteNote(int id) async {
// データベースからメモを削除
await widget.database.delete(
'notes',
where: 'id = ?',
whereArgs: [id],
);
// メモの一覧を更新
_getNotes();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('メモアプリ'),
),
body: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: _notes.length,
itemBuilder: (context, index) {
final note = _notes[index];
return ListTile(
title: Text(note.title),
subtitle: Text(note.content),
trailing: IconButton(
icon: const Icon(Icons.delete),
onPressed: () {
_deleteNote(note.id);
},
),
);
},
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: _titleController,
decoration: const InputDecoration(
hintText: 'タイトル',
),
),
),
const SizedBox(width: 8.0),
Expanded(
child: TextField(
controller: _contentController,
decoration: const InputDecoration(
hintText: '内容',
),
),
),
const SizedBox(width: 8.0),
ElevatedButton(
onPressed: _addNote,
child: const Text('追加'),
),
],
),
),
],
),
);
}
}
class Note {
final int id;
final String title;
final String content;
Note({
required this.id,
required this.title,
required this.content,
});
}
このコードの説明
main.dart
ファイルは、アプリ
Flutter で SQFlite を使ったその他のクエリ方法
query
メソッドの columns
パラメータを使用して、取得する列を指定できます。
Future<List<Map<String, dynamic>>> getUsersWithNamesAndAges() async {
final db = await openDatabase('my_database.db');
final List<Map<String, dynamic>> maps = await db.query(
'users',
columns: ['name', 'age'], // 特定の列のみを取得
);
return maps;
}
WHERE 句を使用して条件を指定する
query
メソッドの where
と whereArgs
パラメータを使用して、クエリ結果を絞り込むことができます。
Future<List<User>> getUsersWhereAgeGreaterThan20() async {
final db = await openDatabase('my_database.db');
final List<Map<String, dynamic>> maps = await db.query(
'users',
where: 'age > ?', // WHERE age > 20
whereArgs: [20],
);
return List.generate(maps.length, (i) {
return User(
id: maps[i]['id'],
name: maps[i]['name'],
age: maps[i]['age'],
);
});
}
ORDER BY 句を使用して結果をソートする
Future<List<User>> getUsersSortedByName() async {
final db = await openDatabase('my_database.db');
final List<Map<String, dynamic>> maps = await db.query(
'users',
orderBy: 'name ASC', // 名前で昇順ソート
);
return List.generate(maps.length, (i) {
return User(
id: maps[i]['id'],
name: maps[i]['name'],
age: maps[i]['age'],
);
});
}
LIMIT 句を使用して結果を制限する
Future<List<User>> getUsersLimitedTo10() async {
final db = await openDatabase('my_database.db');
final List<Map<String, dynamic>> maps = await db.query(
'users',
limit: 10, // 上位 10 件のみ取得
);
return List.generate(maps.length, (i) {
return User(
id: maps[i]['id'],
name: maps[i]['name'],
age: maps[i]['age'],
);
});
}
DISTINCT 句を使用して重複を削除する
Future<List<String>> getDistinctUserNames() async {
final db = await openDatabase('my_database.db');
final List<Map<String, dynamic>> maps = await db.query(
'users',
columns: ['name'], // 名前列のみ取得
distinct: true, // 重複を削除
);
return List.generate(maps.length, (i) => maps[i]['name'] as String);
}
JOIN 句を使用して複数のテーブルを結合する
sqflite
パッケージには、複数のテーブルを結合するための JOIN 句をサポートするメソッドはありません。しかし、JOIN 句をエミュレートするために RAW クエリを使用することができます。
Future<List<UserWithAddress>> getUsersWithAddresses() async {
final db = await openDatabase('my_database.db');
final List<Map<String, dynamic>> maps = await db.rawQuery(
'''
SELECT u.id, u.name, u.age, a.address
FROM users AS u
JOIN addresses AS a ON u.id = a.user_id;
''',
);
return List.generate(maps.length, (i) {
return UserWithAddress(
id: maps[i]['id'],
name: maps[i]['name'],
age: maps[i]['age'],
address: maps[i]['address'],
sqlite dart flutter