플러터(Flutter) 앱에서 데이터베이스를 효과적으로 관리하는 것은 앱의 성능과 유지 보수성을 향상시키는 데 중요한 역할을 한다. 이번 글에서는 Drift를 사용하여 직접 SQL을 작성하지 않고도 플러터 데이터베이스를 구현할 수 있도록 준비하는 방법에 대해 작성한다.
플러터 데이터베이스 목차
Drift
플러터 데이터베이스 SQLite는 낮은 수준의 SQL 작업을 직접 다루지만, Drift는 Dart 기반의 고수준 ORM으로 객체지향적인 방식으로 데이터베이스를 관리한다. Drift는 자동 스키마 관리와 디자인 타임 안전성을 제공하여 데이터 모델링을 더 간편하고 안전하게 만들 수 있다. 프로젝트의 복잡성과 개발자의 편의성에 따라 어떤 것을 사용할지 선택할 수 있다.
패키지 설치
pubspec.yaml에서 필요한 패키지를 설치한다. dev_dependencies는 개발시에만 필요한 패키지들을 나타낸다.
dependencies: ... drift: ^2.13.2 path_provider: ^2.0.0 path: ^1.8.3 get_it: 7.2.0 dev_dependencies: ... build_runner: ^2.2.0 drift_dev: ^2.13.2
모델 구현
플러터 데이터베이스 ORM 라이브러리인 Drift를 활용하여 DiaryDb 클래스에 SQLite 테이블을 간단하게 정의한다. date 컬럼은 날짜를 저장, content 컬럼은 다이어리의 내용, create는 생성일자를 텍스트로 저장한다.
# models/diary_db.dart import 'package:drift/drift.dart'; class DiaryDb extends Table { IntColumn get id => integer().autoIncrement()(); DateTimeColumn get date => dateTime()(); TextColumn get content => text()(); DateTimeColumn get create => dateTime()(); }
DB 등록하기
Drift를 사용하여 SQLite 데이터베이스를 관리하는 LocalDatabase 클래스 정의한다. 데이터 모델로 DiaryDb를 포함하며, watch, insert, delete 등의 메서드를 사용할수록 추가한다.
LazyDatabase를 사용하여 비동기적으로 데이터베이스에 연결한다.
# database/drift_database.dart import 'package:diary/models/diary_db.dart'; import 'package:drift/drift.dart'; import 'package:drift/native.dart'; import 'package:path_provider/path_provider.dart'; import 'package:path/path.dart' as p; import 'dart:io'; // Drift의 코드 생성 도구에 의해 자동으로 생성되는 파일 part 'drift_database.g.dart'; @DriftDatabase( tables: [ DiaryDb, ], ) class LocalDatabase extends _$LocalDatabase { LocalDatabase() : super(_openConnection()); @override int get schemaVersion => 1; // 지정된 날짜에 대한 다이어리 항목을 조회하는 메서드 Stream<List<DiaryDbData>> watchSchedules(DateTime date) => (select(diaryDb)..where((tbl) => tbl.date.equals(date))).watch(); // 다이어리 항목을 추가하는 메서드 Future<int> createSchedule(DiaryDbCompanion date) => into(diaryDb).insert(date); // 지정된 날짜의 다이어리 항목을 삭제하는 메서드 Future<int> removeSchedule(DateTime date) => (delete(diaryDb)..where((tbl) => tbl.date.equals(date))).go(); // 지정된 날짜의 다이어리 항목을 업데이트하는 메서드 Future<int> updateSchedule(DiaryDbCompanion date) => (update(diaryDb)..where((tbl) => tbl.date.equals(date.date.value))) .write(date); } // 비동기적으로 데이터베이스에 연결하기 위한 LazyDatabase 생성 LazyDatabase _openConnection() { return LazyDatabase(() async { final dbFolder = await getApplicationDocumentsDirectory(); final file = File(p.join(dbFolder.path, 'dbsqlite')); return NativeDatabase(file); }); }
DB관련 코드 생성
코드 생성을 통해 쿼리를 작성하는 데 필요한 기능을 생성한다. 터미널에서 flutter pub run build_runner build 명령어를 실행해서 코드를 생성하였다. 만약 안드로이드스튜디오 사용한다면 아래 이미지처럼 Terminal 탭을 이용에 바로 입력할 수 있다.
flutter pub run build_runner build
drift_database.g.dart 파일이 생성된다. drift_database.g.dart 파일은 코드 생성 도구인 build_runner를 사용하여 자동으로 생성되는 파일로, 일반적으로 라이브러리나 프레임워크에서 코드를 생성하는 데 사용된다.
Drift에서는 데이터베이스 모델을 정의한 Dart 파일로부터 SQL 쿼리 및 관련 코드를 생성하고, 그 결과가 drift_database.g.dart 파일에 저장된다. 이 파일들은 빌드 프로세스에서 자동으로 업데이트되며 직접 수정하면 안 된다.
마무리
Drift를 활용하여 효과적인 데이터베이스 관리를 할 수 있도록 준비하는 과정을 맞췄습니다. 다음 포스팅에서는 지금까지 Table_calendar, Navigator, DatePicker등으로 만든 앱에서 기본적인 CRUD (Create, Read, Update, Delete) 작업을 수행하는 방법에 대해서 작성하겠습니다. 읽어주셔서 감사합니다.
전체 코드는 링크에서 확인할 수 있습니다.