[Flutter] SQLite 사용하기

jong·2021년 6월 10일
0

Flutter

목록 보기
6/9

잡담

DB를 공부하고 처음으로 실질적으로 사용한 게 sqlite이다. MySql보다 간편하게 사용할 수 있다보니 C#에서 애용했는데, 앱을 제작할 때 설정값들을 sqlite를 주로 사용한다고 해서 도전하게 되었다.

SQLite

의존성 추가

pubspec.yaml

dependencies:
    flutter:
        sdk: flutter
    sqflite: ^1.3.0
    path_provider: ^2.0.2
    path: ^1.8.0
  • sqflite 패키지는 SQLite 데이터베이스를 사용할 수 있도록 여러 클래스와 함수를 제공한다.
    https://pub.dev/packages/sqflite#-installing-tab-
  • path 패키지는 디스크에 저장할 데이터베이스의 위치를 정확히 정의할 수 있는 함수를 제공한다.
    https://pub.dev/packages/path
  • path_provider 패키지는 Android와 iOS에서 필요한 경로를 알려주는 패키지이다. db 파일을 저장할 위치를 알아내는 용도로 사용된다.

출처 Flutter-ko.dev
참고 dalgonakit

.dart


사진과 같이 프로젝트를 구성해 준다. 어떻게 프로젝트를 관리할지는 본인의 자유.

본 글의 예제는 다른 곳들과 마찬가지로 Dog로 한다.

Dog 데이터 모델 정의

model>dog.dart

class Dog {
  final int id;
  final String name;
  final int age;

  Dog({this.id, this.name, this.age});

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'name': name,
      'age': age,
    };
  }

  
  String toString() {
    return 'Dog{id: $id, name: $name, age: $age}';
  }
}

강아지를 구분할 수 있는 고유의 id, 이름, 나이를 가지고 있는 모델을 만든다.

DB 사용하기

효율적인 DB 사용을 위해 Dog DB를 제어할 클래스를 만들어준다.
db>dbHelper.dart

class DBHelper {
  var _db;
  
  Future<Database> get database async {
    if (_db != null) return _db;
    _db = openDatabase(join(await getDatabasesPath(), 'Dog.db'),
        onCreate: (db, version) => _createDb(db), version: 1);
    return _db;
  }
  
  static void _createDb(Database db) {
    db.execute(
      "CREATE TABLE Dog(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)",
    );
  }
}

DB를 불러오고, 없으면 DB를 생성하는 기능을 만들어준다.

db>dbHelper.dart>DBHelper

  Future<void> insertDog(Dog dog) async {
    final db = await database;

    await db.insert("Dog", dog.toMap(),
        conflictAlgorithm: ConflictAlgorithm.replace);
  }

  Future<List<Dog>> getAllDog() async {
    final db = await database;

    final List<Map<String, dynamic>> maps = await db.query('Dog');

    return List.generate(maps.length, (i) {
      return Dog(
        id: maps[i]['id'],
        name: maps[i]['name'],
        age: maps[i]['age'],
      );
    });
  }

  Future<dynamic> getDog(int id) async {
    final db = await database;

    final List<Map<String, dynamic>> maps = (await db.query(
      'Dog',
      where: 'id = ?',
      whereArgs: [id],
    ));

    return maps.isNotEmpty ? maps : null;
  }

  Future<void> updateDog(Dog dog) async {
    final db = await database;

    await db.update(
      "Dog",
      dog.toMap(),
      where: "id = ?",
      whereArgs: [dog.id],
    );
  }

  Future<void> deleteDog(int id) async {
    final db = await database;

    await db.delete(
      "Dog",
      where: "id = ?",
      whereArgs: [id],
    );
  }

기본적으로 DB에 사용할 기능들이다. 데이터를 추가하고, 삭제하고, 업데이트하고.

불러오기

코드를 작성하였으니 main에서 불러와서 사용해야 한다.

예시로 다음의 Dog를 추가하겠다.

  • id: 1
  • name: Mini
  • age: 8
    DBHelper dbHelper = DBHelper();
    dbHelper.insertDog(Dog(id: 1, name: 'Mini', age: 8));

저장한 모든 Dog를 불러오려면 다음의 코드를 사용한다.

    DBHelper dbHelper = DBHelper();
    dbHelper.getAllDog().then((value) => value.forEach((element) {
          print(
              "id: ${element.id}\nname: ${element.name}\nage: ${element.age}");
        }));

결과

I/flutter ( 1945): id: 1
I/flutter ( 1945): name: Mini
I/flutter ( 1945): age: 8
I/flutter ( 1945): id: 12
I/flutter ( 1945): name: d
I/flutter ( 1945): age: 12
I/flutter ( 1945): id: 13
I/flutter ( 1945): name: d
I/flutter ( 1945): age: 12

이전에 테스트했던 것들까지 다 나왔다.

이번엔 특정 id만 지정해서 정보를 받아오고자 한다.
(이보다 효율적이고 좋은 방법이 있다면 댓글 부탁드립니다.)

    DBHelper dbHelper = DBHelper();
    
    dbHelper.getDog(12).then((value) {
      if (value is List<Map<String, dynamic>>) {
        value.forEach((element) {
          element.forEach((key, value) {
            print('$key: $value');
          });
        });
      } else {
        print('null');
      }
    });

결과

I/flutter ( 1945): id: 12
I/flutter ( 1945): name: d
I/flutter ( 1945): age: 12

원하는 정보들이 잘 나왔다.

profile
공부 기록

0개의 댓글