LoginSignup
1
2

More than 3 years have passed since last update.

flutter sqflite 初歩歩の歩

Last updated at Posted at 2021-06-05

自分用に書いたメモです。
間違っている部分やおかしな部分があったらコメントください!

この記事を書くにあたってこちらの2つのサイトを参考にさせていただきました。
FlutterのシンプルなSQFliteデータベースの例
Flutterでsqliteを使ったTodoアプリを作る

パッケージ
sqflite
path_provider
uuid

pubspec.yaml
  sqflite: ^2.0.0
  path_provider: ^2.0.2
  uuid: ^3.0.4

モデル

lib/db/memo.dart
import 'package:uuid/uuid.dart';

class Memo {
  late int id;
  late DateTime date;
  late String note;

  Memo({
    required this.id,
    required this.date,
    required this.note,
  });

  Memo.newMemo() {
    id = Uuid().v4();    
    date = DateTime.now();
    note = "";
  }

  // SQLiteではDateTime型を保存できないためString型に変換する
  Map<String, dynamic> toMap() => {
        "id": id,
        // DateTime型を、文字列で保存する。
        "date": date.toUtc().toIso8601String(),
        "note": note,
      };

  factory Memo.fromMap(Map<String, dynamic> json) => Memo(
        id: json["id"],
        // 文字列で保存されているため、DateTime型に変換する。
        date: DateTime.parse(json["date"]).toLocal(),
        note: json["note"],
      );
}

DatabaseProvider

lib/db/dbProvider.dart
import 'dart:io';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';

import 'package:article_project/db/memo.dart';

class DBProvider {
  final _databaseName = 'my_database.db';
  final _databaseVersion = 1;

  final _tableName = 'memo';
  final _columnId = 'id';
  final _columnDate = 'date';
  final _columnNote = 'note';

  DBProvider._();

  static final DBProvider instance = DBProvider._();
  Database? _database;

  // Databaseが存在するかどうか確認して、あったら返す。
  Future<Database> get database async {
    if (_database != null) return _database!;
    // Databaseがない場合に作成する。
    _database = await _initDatabase();
    return _database!;
  }

  Future<Database> _initDatabase() async {
    Directory documentDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentDirectory.path, _databaseName);
    return await openDatabase(
      path,
      version: _databaseVersion,
      onCreate: _onCreate,
    );
  }

  Future<void> _onCreate(Database db, int version) async {
    await db.execute('''
    CREATE TABLE $_tableName (
    $_columnId TEXT PRIMARY KEY,
    $_columnDate TEXT NOT NULL,
    $_columnNote TEXT NOT NULL
    )''');
  }

  Future<int> insert(Memo row) async {
    Database db = await instance.database;
    return await db.insert(_tableName, row.toMap());
  }

  Future<List<Memo>> getAllRows() async {
    Database db = await instance.database;
    var res = await db.query(_tableName);
    // Databaseの中身を確認して、あった場合Listにして無い場合は空のListを返す。
    List<Memo> list = 
        res.isNotEmpty ? res.map((m) => Memo.fromMap(m)).toList() : [];
    return list;
  }

  Future<Memo?> getSelectRow(String id) async {
    Database db = await instance.database;
    List<Map> maps = await db.query(_tableName,
        columns: [_columnId, _columnDate, _columnNote],
        where: '$_columnId = ?',
        whereArgs: [id]);
    if (maps.isNotEmpty) {
      return Memo.fromMap(Map<String, dynamic>.from(maps.first));
    }
    return null;
  }

  Future<int> update(Memo row) async {
    Database db = await instance.database;
    return await db.update(
      _tableName,
      row.toMap(),
      where: '$_columnId = ?',
      whereArgs: [row.id],
    );
  }

  Future<int> delete(String id) async {
    Database db = await instance.database;
    return await db.delete(
      _tableName,
      where: '$_columnId = ?',
      whereArgs: [id],
    );
  }
}

Main

main.dart
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';                 // ++

import 'package:my_project/db/memo.dart';        // ++
import 'package:my_project/db/dbProvider.dart';  // ++

void main() {
  runApp(MyApp());
}

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

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
//  int _counter = 0;

//  void _incrementCounter() {
//    setState(() {
//      _counter++;
//    });
//  }

  final dbProvider = DBProvider.instance;        // ++

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      /** --- 追加 ここから --- **/
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              child: Text(
                'insert',
                style: TextStyle(fontSize: 20),
              ),
              onPressed: _insert,
            ),
            ElevatedButton(
              child: Text(
                'query',
                style: TextStyle(fontSize: 20),
              ),
              onPressed: _query,
            ),
            ElevatedButton(
              child: Text(
                'update',
                style: TextStyle(fontSize: 20),
              ),
              onPressed: _update,
            ),
            ElevatedButton(
              child: Text(
                'delete',
                style: TextStyle(fontSize: 20),
              ),
              onPressed: _delete,
            ),
          ],
        ),
      ),
      /** --- 追加 ここまで -- **/
//      body: Center(
//        child: Column(
//          mainAxisAlignment: MainAxisAlignment.center,
//          children: <Widget>[
//            Text(
//              'You have pushed the button this many times:',
//            ),
//            Text(
//              '$_counter',
//              style: Theme.of(context).textTheme.headline4,
//            ),
//          ],
//        ),
//      ),
//      floatingActionButton: FloatingActionButton(
//        onPressed: _incrementCounter,
//        tooltip: 'Increment',
//        child: Icon(Icons.add),
//      ),
    );
  }

  /** --- 追加 ここから --- **/
  void _insert() async {
    Memo row = Memo.newMemo();
    row.note = 'test Text 000';
    final id = await dbProvider.insert(row);
    print('inserted row id: $id');
  }

  void _query() async {
    final allRows = await dbProvider.getAllRows();
    print('query all rows:');
    allRows.forEach(print);
  }

  void _update() async {
    final rowsAffected = await dbProvider.update(Memo.newMemo());
    print('updated $rowsAffected row(s)');
  }

  void _delete() async {
    String uuid = Uuid().v4();
    final rowsDeleted = await dbProvider.delete(uuid);
    print('deleted $rowsDeleted row(s): row $uuid');
  }
  /** --- 追加 ここまで --- **/
}

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2