welcome to my blog

[Flutter] database 사용 본문

Flutter

[Flutter] database 사용

_annie_ 2021. 11. 3. 20:05
728x90

어플을 새로 켤때마다 초기화되지만, database를 이용하면 정보를 저장했다가 불러올 수 있다.

간단하게 database 생성, 추가, 읽어오기를 테스트 해보겠다. (수정, 삭제는 다음 포스팅에..)

 

설치 라이브러리 : sqflite, path

 

path 라이브러리 : 경로 관련 라이브러리

join() : 경로를 병합시켜준다.

예시)

p.join('path', 'to', 'foo'); // -> 'path/to/foo'

 

 

sqflite 라이브러리 : database 관리 라이브러리

getDatabasesPath() : 기본 데이터베이스 경로를 가져온다.

일반적으로 Android는 data/data/ , iOS는 Documents 디렉토리 이다.

Future<String> getDatabasesPath() => databaseFactory.getDatabasesPath();

 

  • 테스트코드
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

class TestDatabase {
  var _path = '';
  var _database;

  void setPath() async {
    print('setPath !!!');
    var databasePath = await getDatabasesPath();
    _path = join(databasePath, 'demo123.db');
    print('path : ${_path}');
  }

  void open() async {
    print('open !!!');
    Database database = await openDatabase(_path, version: 1,
        onCreate: (Database db, int version) async {
          // When creating the db, create the table
          await db.execute(
              'CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT, value INTEGER, num REAL)');
        });
    _database = database;
  }

  void insert() async {
    print('insert !!!');
    await _database.transaction((txn) async {
      int id1 = await txn.rawInsert(
          'INSERT INTO Test(name, value, num) VALUES("some name", 1234, 456.789)');
      print('inserted1: $id1');
      int id2 = await txn.rawInsert(
          'INSERT INTO Test(name, value, num) VALUES(?, ?, ?)',
          ['another name', 12345678, 3.1416]);
      print('inserted2: $id2');
    });
  }

  void getData() async {
    print('getData !!!');
    List<Map> list = await _database.rawQuery('SELECT * FROM Test');    
    print(list);
  }
}

openDatabase : database열기 (없으면 작성한 경로로 생성)

 

 

sql 참고 : https://github.com/tekartik/sqflite/blob/master/sqflite/doc/sql.md

 

GitHub - tekartik/sqflite: SQLite flutter plugin

SQLite flutter plugin. Contribute to tekartik/sqflite development by creating an account on GitHub.

github.com

execute : return 값이 없는 커맨드를 위한 명령어 (ex. table 생성)

// Create a table
await db.execute('CREATE TABLE my_table (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, type TEXT)');

insert : 테이블에 데이터 삽입을 위한 명령어. 내부 id(정수) 를 반환한다.

int recordId = await db.insert('my_table', {'name': 'my_name', 'type': 'my_type'});

 

query : 테이블 데이터를 읽기위한 명령어. map list 를 반환한다.

var list = await db.query('my_table', columns: ['name', 'type']);

 

delete : 테이블 내부 항목을 삭제하기 위한 명령어. 삭제 된 행 개수를 반환한다.

var count = await db.delete('my_table', where: 'name = ?', whereArgs: ['cat']);

 

update : 테이블 항목을 업데이트(수정)하기 위한 명령어. 업데이트 된 행 개수를 반환한다.

var count = await db.update('my_table', {'name': 'new cat name'}, where: 'name = ?', whereArgs: ['cat']);

 

transaction : 하나의 명령어라도 실패하면 이전으로 되돌린다.

구글번역 : 트랜잭션은 '전부 아니면 전무' 시나리오를 처리한다. 하나의 명령이 실패하고 오류가 발생하면 다른 모든 명령이 되돌려진다.

await db.transaction((txn) async {
  await txn.insert('my_table', {'name': 'my_name'});
  await txn.delete('my_table', where: 'name = ?', whereArgs: ['cat']);
});
  • Make sure to sure the inner transaction object - txn in the code above - is used in a transaction (using the db object itself will cause a deadlock),

       내부 트랜잭션 객체( txn위 코드에서)가 트랜잭션에서 사용 되는지 확인하십시오 ( db객체 자체를 사용하면 교착 상태가 발생함).

  • You can throw an error during a transaction to cancel a transaction,

       트랜잭션 중 오류를 발생시켜 트랜잭션을 취소할 수 있으며,

  • When an error is thrown during a transaction, the action is cancelled right away and previous commandsin the transaction are reverted,

        트랜잭션 중 오류가 발생하면 즉시 작업을 취소하고 트랜잭션의 이전 명령을 되돌리며,

  • No other concurrent modification on the database (even from an outside process) can happen during a transaction,

       트랜잭션 중에는 데이터베이스에 대한 다른 동시 수정(외부 프로세스에서도)이 발생할 수 없습니다.       

  • The inner part of the transaction is called only once, it is up to the developer to handle a try-again loop - assuming it can succeed at some point.

       트랜잭션의 내부 부분은 한 번만 호출되며, 다시 시도 루프를 처리하는 것은 개발자에게 달려 있습니다.

 

parameters

// good
int recordId = await db.rawInsert('INSERT INTO my_table(name, year) VALUES (?, ?)', ['my_name', 2019]);
// bad
int recordId = await db.rawInsert("INSERT INTO my_table(name, year) VALUES ('my_name', 2019)");

 

rawInsert : 원시 sql문. 작성한 쿼리 그대로 실행

물음표는 인수의 개수와 일치해야한다. 

 

한번에 추가 (filled 및 join 이용)

List.filled(inArgsCount, '?').join(',')
var inArgs = ['cat', 'dog', 'fish'];
var list = await db.query('my_table',
  where: 'name IN (${List.filled(inArgs.length, '?').join(',')})',
  whereArgs: inArgs);

 

null값의 경우

var list = await db.query('my_table', columns: ['name'], where: 'type IS NULL');

'WHERE my_col = ?', [null] 이라고 쓰는대신 위처럼 'WHERE my_col IS NULL' 혹은 'WHERE my_col IS NOT NULL' 로 사용

 

 

 

728x90
반응형