Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- Got
- C++
- Stream
- ML
- MATLAB
- pytorch
- BFS
- MDP
- Dreamhack
- ARM
- system hacking
- 영상처리
- bloc
- DART
- BAEKJOON
- 파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습
- Algorithm
- rao
- Widget
- 백준
- fastapi를 사용한 파이썬 웹 개발
- llm을 활용 단어장 앱 개발일지
- study book
- PCA
- FastAPI
- Computer Architecture
- BOF
- Kaggle
- Flutter
- Image Processing
Archives
- Today
- Total
Bull
[Flutter] Drift 사용 예제 본문
SQL 쉽게 핸들가능한 ORM 라이브러리
라이브러리
2025.03.23 기준
dependencies:
drift: ^2.26.0
drift_flutter: ^0.2.4
path_provider: ^2.1.5
path: ^1.9.0
drift_dev: ^2.26.0
build_runner: ^2.4.15
database 정의
database/app_database.dart
class Todos extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get title => text().withLength(min: 1, max: 50)();
BoolColumn get completed => boolean().withDefault(Constant(false))();
}
필드 | 설명 |
---|---|
id | 정수형 기본키, 자동 증가 |
title | 최소 1자, 최대 50자의 텍스트 |
completed | 완료 여부 (bool), 기본값은 false |
withLength : 길이 설정 |
|
withDefault : 기본값 설정 |
@DriftDatabase(tables: [Todos])
class AppDatabase extends _$AppDatabase {
AppDatabase() : super(_openConnection());
@override
int get schemaVersion => 1;
Future<List<Todo>> getAllTodos() => select(todos).get();
Stream<List<Todo>> watchAllTodos() => select(todos).watch();
Future insertTodo(TodosCompanion todo) => into(todos).insert(todo);
Future updateTodo(Todo todo) => update(todos).replace(todo);
Future deleteTodo(Todo todo) => delete(todos).delete(todo);
}
@DriftDatabase(tables: [Todos])
:
- 이 클래스(AppDatabase)는 Drift 데이터베이스이고, 여기에 포함된 테이블은 Todos다.
- 툴/프레임워크/컴파일러가 인식하기 위해 존재
- “이건 특별한 역할이 있어!”
- build_runner가 이 애너테이션을 보고 _$AppDatabase와 관련된 코드를 자동으로 생성
_$AppDatabase
:
- drift가 generate 해주는 database 클래스
schemaVersion
:
- 스키마 형태가 바뀌면 올려줘야 함.
Future<List<Todo>> getAllTodos() => select(todos).get();
Stream<List<Todo>> watchAllTodos() => select(todos).watch();
Future insertTodo(TodosCompanion todo) => into(todos).insert(todo);
Future updateTodo(Todo todo) => update(todos).replace(todo);
Future deleteTodo(Todo todo) => delete(todos).delete(todo);
select
:
메서드 | 의미 |
---|---|
.get() | 한 번 데이터를 가져옴 (한 번만 실행), 한 번만 읽는 경우에만 하면 됌. |
.watch() | 스트림으로 감시 (데이터가 바뀌면 자동 업데이트됨) |
.where(...) | 조건절 추가 가능 |
insert
:
TodosCompanion
: DB에 값 넣을 땐 이거 사용해야 됌
update
:
- 업데이트하는데 전체리스트를 불러오고,
todos
는 drift에 의해 이미 g파일에 생성되어 있음. 즉 전체테이블리스트.replace
를 통해 일치하는 id에서 바꿔짐.
delete
:
- 이것도 마찬가지로 id에 의해 삭제.
LazyDatabase _openConnection() {
return LazyDatabase(() async {
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'db.sqlite'));
return NativeDatabase(file);
});
}
- SQLite 파일을 앱 내에서 저장할 위치를 설정하고, DB 연결을 열어주는 함수
- 중요한 건, 템플릿처럼 Default로 쓰면 됌.
LazyDatabase(...)
:
- Drift에서 제공하는 특별한 객체
- DB가 실제로 필요할 때 연결
- 앱 시작할 때 미리 열지 않기 때문에 효율적
- 앱 켜자마자 DB 연결 x → insert, query할 때 연결 o
() async { ... }
:
- 데이터베이스 파일은 디스크에 저장되기 때문에, 경로 탐색이 비동기
- 그래서 함수도 async
getApplicationDocumentsDirectory()
:
- 이건 앱 전용 저장소 경로를 가져오는 함수
- Android에서는 /data/data/com.yourapp/files/ 같은 위치
- 앱 외부에서 접근 불가한 안전한 저장소
File(p.join(dbFolder.path, 'db.sqlite'))
:
- 이 줄에서 SQLite 데이터베이스 파일 경로를 설정
- p.join(...) 은 경로를 OS에 맞게 자동으로 이어주는 역할 (/ 또는 \ 등 처리)
return NativeDatabase(file)
- Drift에게 “여기 이 파일에 DB 저장해줘” 라고 알려줌
- 실제 DB는 이 파일에 쓰이고 읽힘
g파일 생성
flutter pub run build_runner build
사용 방법
- db 인스턴스를 만든다.
final db = AppDatabase();
- 스트림에 watch 등록.
StreamBuilder<List<Todo>>( stream: db.watchAllTodos(), builder: (context, snapshot) { }, ),
- snapshot을 통해 해당 시점의 data 확인.
- 사용에 맞게
db.method()
로 호출.builder: (context, snapshot) { final todos = snapshot.data ?? []; return ListView.builder( itemCount: todos.length, itemBuilder: (_, index) { final todo = todos[index]; return ListTile( title: Text(todo.title), trailing: Checkbox( value: todo.completed, onChanged: (val) { db.updateTodo(todo.copyWith(completed: val)); }, ), ); }, ); },
main.dart
import 'package:flutter/material.dart';
import 'database/app_database.dart';
import 'package:drift/drift.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final db = AppDatabase();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Drift Demo',
home: Scaffold(
appBar: AppBar(title: Text('TODO List')),
body: StreamBuilder<List<Todo>>(
stream: db.watchAllTodos(),
builder: (context, snapshot) {
final todos = snapshot.data ?? [];
return ListView.builder(
itemCount: todos.length,
itemBuilder: (_, index) {
final todo = todos[index];
return ListTile(
title: Text(todo.title),
trailing: Checkbox(
value: todo.completed,
onChanged: (val) {
db.updateTodo(todo.copyWith(completed: val));
},
),
);
},
);
},
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
db.insertTodo(
TodosCompanion(title: Value('New Todo')),
);
},
),
),
);
}
}
'Software Framework > Flutter' 카테고리의 다른 글
[Flutter::Widget] 캡스톤 디자인에서 만든 앱 디자인 아카이브용 (0) | 2025.05.26 |
---|---|
[Flutter::Bloc::utility] bloc_concurrency 약식 정리 (0) | 2024.11.26 |
[Flutter::Package] gafa_indicator 제작 (1) | 2024.11.16 |
[Flutter::State] RiverPod Tutorial - Getting Started Review (1) | 2024.10.28 |
[Flutter::trubleshooting] flutter_launcher_icons black background trubleshooting (android) (0) | 2024.09.29 |