Flutter/Package

[Flutter] Sqlflite

찌김이 2022. 7. 24. 19:10
728x90
반응형

Flutter 에서 로컬 데이터베이스 패키지 중 하나인 Sqlflite 에 대해서 포스팅합니다.

간단한 화면과 CRUD 를 구현해보려고 합니다.

 

sqflite | Flutter Package

Flutter plugin for SQLite, a self-contained, high-reliability, embedded, SQL database engine.

pub.dev

 

pubspec.yaml 

dependencies:
  sqflite: ^2.0.3

 

 

todo.dart

  • 로컬DB 로 흔히 구현하는 Todo 로 만들어봤습니다.
  • autoincrement 로 제약을 걸 예정인 id 는 nullable 로 두겠습니다.
class Todo {
  String title;
  bool done;
  int? id;

  Todo({
    required this.title,
    required this.done,
    required this.id,
  });

  factory Todo.fromJson(Map<String, dynamic> json) => Todo(
    title: json['title'],
    done: json['done'] == 1,
    id : json['id']
  );

  Map<String, dynamic> toJson() => {
    'id' : id,
    'title' : title,
    'done' : done ? 1 : 0
  };
}

 

todo_db_helper.dart

  • 로컬 DB 를 사용하게 해주는 Helper 클래스를 구현해줍니다.
  • 여기에서 테이블 생성과 CRUD 를 사용할 수 있게 작성합니다.
import 'package:flutter_sqlflite/todo.dart';
import 'package:sqflite/sqflite.dart';

const tableTodo = 'todo';
const columnId = 'id';
const columnTitle = 'title';
const columnDone = 'done';

class TodoDbHelper {
  late Database db;

  Future<TodoDbHelper> initDB() async {
    db = await openDatabase(
      'path',
      version: 1,
      onCreate: _onCreate,
    );
    return this;
  }

  void _onCreate(Database db, int version) async {
    await db.execute(
        "create table $tableTodo ("
            "$columnId integer primary key autoincrement not null,"
            "$columnTitle text not null,"
            "$columnDone integer not null)"
    );
  }

  Future<List<Todo>> findAll() async
    => (await db.query(tableTodo, orderBy : 'id DESC'))
            .map(Todo.fromJson)
            .toList();

  Future<Todo> insert(Todo todo) async {
    todo.id = await db.insert(
      tableTodo,
      todo.toJson(),
    );
    return todo;
  }

  Future<int> delete(int id) async {
    return await db.delete(
      tableTodo,
      where: '$columnId = ?',
      whereArgs: [id],
    );
  }

  Future<int> update(Todo todo) async {
    return await db.update(
      tableTodo,
      todo.toJson(),
      where: '$columnId = ?',
      whereArgs: [todo.id],
    );
  }

  Future close() async => db.close();
}

 

todo_screen.dart

  • 예시 화면 입니다. 여기서는 간단한 동작으로만 CRUD 가 구현되어있습니다.
  • FutureBuilder 를 이용하여 todo 목록 정보를 가져옵니다.
import 'package:flutter/material.dart';
import 'package:flutter_sqlflite/todo.dart';
import 'package:flutter_sqlflite/todo_db_helper.dart';

class TodoScreen extends StatefulWidget {
  const TodoScreen({Key? key}) : super(key: key);

  @override
  State<TodoScreen> createState() => _TodoScreenState();
}

class _TodoScreenState extends State<TodoScreen> {
  late TodoDbHelper todoDbHelper;

  Future<List<Todo>> _init() async {
    todoDbHelper = await TodoDbHelper().initDB();
    return todoDbHelper.findAll();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder(
        future: _init(),
        builder: (context, snapshot) {
          // loading
          if (!snapshot.hasData) {
            return const Center(
              child: CircularProgressIndicator(),
            );
          }
          
          // empty
          if (snapshot.data!.isEmpty) {
            return const Center(
              child: Text(
                'Todo is empty',
                style: TextStyle(
                  fontSize: 20.0,
                ),
              ),
            );
          }

          return ListView(
            children: snapshot.data!
                .map(
                  (e) => ListTile(
                    title: Text('${e.title} ${e.id}'),
                    leading: updateBtn(e),
                    trailing: deleteBtn(e.id!),
                  ),
                )
                .toList(),
          );
        },
      ),
      floatingActionButton: addBtn(),
    );
  }

  Widget deleteBtn(int id) => IconButton(
        onPressed: () {
          setState(() {
            todoDbHelper.delete(id);
          });
        },
        icon: const Icon(Icons.delete_forever),
      );

  Widget updateBtn(Todo todo) => IconButton(
        onPressed: () {
          setState(() {
            var title =
                todo.title.contains('update') ? 'title' : 'update title';

            todoDbHelper.update(Todo(title: title, done: false, id: todo.id));
          });
        },
        icon: const Icon(Icons.update_sharp),
      );

  FloatingActionButton addBtn() => FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          setState(() {
            todoDbHelper.insert(
              Todo(
                title: 'title',
                done: true,
                id: null,
              ),
            );
          });
        },
      );
}

 

 

 

728x90
반응형

'Flutter > Package' 카테고리의 다른 글

[Flutter] Hive  (0) 2022.07.26
[Flutter] Drift  (0) 2022.07.25
[Flutter] Freezed  (0) 2022.07.22
[Flutter] TableCalendar ⑤ - 유용한 기능들  (0) 2022.07.20
[Flutter] TableCalendar ④ - 달력 꾸미기 (CalendarStyle)  (3) 2022.07.18