안녕하세요 지금까지 플러터(Flutter)에서 화면 간 데이터 전달을 구현하여 입력한 데이터를 표시하는 기능을 만들어보았습니다. 더 나아가 앱을 재실행해도 그 데이터가 유지되도록 플러터 데이터베이스 사용방법에 대해서 작성합니다.

플러터 데이터베이스 사용법 목차
패키지 설치
Flutter 앱에서 데이터를 영구적으로 저장하기 위해서는 sqflite와 날짜를 표시해줄 intl 패키지가 필요합니다. 이 패키지들을 프로젝트에 추가하려면, pubspec.yaml 파일에 다음과 같이 의존성을 추가해야 합니다
dependencies:
flutter:
sdk: flutter
path: ^1.8.3
sqflite: ^2.0.0
intl: ^0.18.1데이터베이스
데이터베이스는 다양한 유형의 애플리케이션에서 필수적으로 사용되는 중요한 구성요소입니다. 앱을 개발하기 위해서 데이터를 CRUD: Create(생성), Read(읽기), Update(갱신), Delete(삭제) 하는 쿼리에 대해서는 반드시 알아야됩니다. 아래글에서 간단한 사용법을 참고하세요
데이터 모델 생성
데이터를 효율적으로 관리하기 위해, 먼저 메모 데이터를 위한 모델을 생성해야 합니다. MemoData 클래스는 메모의 내용, 생성 날짜 및 시간, 그리고 고유 ID를 포함합니다
// MemoData 클래스 정의: 메모 데이터를 위한 모델
class MemoData {
int? id; // 메모의 고유 ID, nullable 타입으로 선언되어 있어서 null일 수 있음
String content; // 메모의 내용을 저장하는 변수, 필수 입력 필드
final DateTime createAt; // 메모가 생성된 시간을 저장하는 변수, final로 선언되어 생성 후 변경 불가
// 생성자: id(옵션), content, createAt(필수)를 받아 객체를 초기화함
MemoData({this.id, required this.content, required this.createAt});
// toMap 메서드: 객체를 Map<String, dynamic>으로 변환해주는 메서드
// Firestore 등의 데이터베이스에 저장하기 위한 준비 과정에서 사용될 수 있음
Map<String, dynamic> toMap() {
return {
'id': id, // id를 Map에 추가, null일 수 있음
'content': content, // content를 Map에 추가
'createAt': createAt.toIso8601String(), // createAt을 ISO8601 문자열 형식으로 변환하여 Map에 추가
};
}
}데이터베이스 헬퍼 클래스
데이터를 저장하고 관리하기 위해 DatabaseHelper 클래스를 생성합니다. 이 클래스는 데이터베이스 초기화, 메모 목록 조회, 메모 추가 및 삭제 기능을 담당합니다.
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import '../models/memo_data.dart';
// DatabaseHelper 클래스 정의: 데이터베이스 관련 작업을 도와주는 유틸리티 클래스
class DatabaseHelper {
static Database? _database; // 데이터베이스 인스턴스를 저장하는 private static 변수, nullable
// initDatabase 메서드: 데이터베이스 초기화 및 생성
Future<void> initDatabase() async {
if (_database == null) { // _database가 null인 경우에만 실행
var databasesPath = await getDatabasesPath(); // 데이터베이스 경로를 가져옴
String path = join(databasesPath, 'memos.db'); // 'memos.db' 파일로 경로를 조합
// 데이터베이스 열기 또는 생성
_database = await openDatabase(path, version: 1,
onCreate: (Database db, int version) async {
// 데이터베이스를 처음 생성할 때 호출됨, 메모 테이블 생성
await db.execute('''
CREATE TABLE memos(
id INTEGER PRIMARY KEY AUTOINCREMENT,
content TEXT,
createAt TEXT
)
''');
});
}
}
// getMemos 메서드: 모든 메모를 가져오는 메서드
Future<List<MemoData>> getMemos() async {
await initDatabase(); // 데이터베이스 초기화
List<Map<String, dynamic>> maps = await _database!.query('memos'); // 'memos' 테이블의 모든 데이터를 조회
// 조회한 데이터를 MemoData 객체 리스트로 변환
return List.generate(maps.length, (index) {
return MemoData(
id: maps[index]['id'], // id 값
content: maps[index]['content'], // content 값
createAt: DateTime.parse(maps[index]['createAt'])); // createAt 값을 DateTime 객체로 변환
});
}
// insertMemo 메서드: 새로운 메모를 데이터베이스에 추가
Future<int> insertMemo(MemoData memo) async {
await initDatabase(); // 데이터베이스 초기화
return await _database!.insert('memos', memo.toMap()); // 'memos' 테이블에 메모 데이터 삽입
}
// deleteMemo 메서드: 특정 id를 가진 메모를 데이터베이스에서 삭제
Future<void> deleteMemo(int id) async {
await initDatabase(); // 데이터베이스 초기화
await _database!.delete(
'memos',
where: 'id = ?', // id가 일치하는 레코드를 찾음
whereArgs: [id], // 삭제할 메모의 id
);
}
}
앱 초기화 및 메모 관리
앱의 메인 페이지에서 DatabaseHelper를 사용하여 메모를 관리합니다. 사용자가 앱을 사용하여 메모를 생성하고, 조회하고, 삭제할 수 있도록 합니다
// MyMemoAppPage 위젯의 상태 클래스 정의
class _MyMemoAppPageState extends State<MyMemoAppPage> {
DatabaseHelper dbHelper = DatabaseHelper(); // DatabaseHelper 인스턴스 생성
late Future<List<MemoData>> memos; // 비동기적으로 메모 데이터를 불러올 Future 변수 선언
@override
void initState() {
// initState 메서드: 위젯의 상태 객체가 생성될 때 호출됨
super.initState(); // 부모 클래스의 initState 호출
memos = dbHelper.getMemos(); // DatabaseHelper를 통해 메모 데이터를 비동기적으로 불러옴
}
// 이하 코드 생략...
}메모 생성버튼
사용자가 버튼을 클릭하면 MemoInputPage 화면으로 이동합니다. 사용자가 MemoInputPage에서 메모 작성 후 돌아오면, then 콜백이 실행되며, 새로 작성된 메모가 있을 경우 (value != null), 상태 업데이트를 통해 새 메모를 데이터베이스에 추가하고 메모 목록을 갱신합니다.
// 아이콘 버튼 위젯: 사용자가 새 메모를 작성할 수 있게 하는 버튼
IconButton(
onPressed: () {
// 버튼 클릭 시, MemoInputPage로 화면 전환
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MemoInputPage()),
).then((value) {
// MemoInputPage에서 돌아올 때 실행되는 콜백
if (value != null) {
// 사용자가 새 메모 입력 후 돌아왔을 경우
setState(() {
// 새로 입력된 메모를 데이터베이스에 추가하고, 메모 리스트를 다시 불러옴
dbHelper.insertMemo(
MemoData(content: value, createAt: DateTime.now()));
memos = dbHelper.getMemos();
});
}
});
},
style: IconButton.styleFrom(foregroundColor: Colors.white), // 버튼 스타일 지정
icon: Icon(Icons.create), // 버튼 아이콘 지정
),메모 삭제버튼
이 버튼을 클릭하면, 해당 메모의 id를 사용하여 DatabaseHelper 클래스의 deleteMemo 메소드를 호출하여 데이터베이스에서 메모를 삭제합니다.
// ListTile 위젯 반환: 각 메모를 나타내는 UI 구성요소
return ListTile(
title: Text(memo.content), // 메모의 내용을 제목으로 표시
subtitle: Text(DateFormat('yy/MM/dd').format(memo.createAt)), // 메모 생성 날짜를 부제목으로 표시, 'yy/MM/dd' 형식으로 날짜 포맷
trailing: IconButton(
icon: Icon(Icons.delete), // 삭제 아이콘 버튼
onPressed: () async {
// 아이콘 버튼 클릭 시 비동기로 실행되는 콜백 함수
await dbHelper.deleteMemo(memo.id!); // dbHelper를 통해 해당 메모 삭제, '!'를 사용하여 null이 아님을 보증
setState(() {
// 메모 삭제 후 상태 업데이트
memos = dbHelper.getMemos(); // 메모 리스트를 다시 불러와서 갱신, 삭제된 메모 반영
});
},
),
);
마무리
사용자가 메모를 추가하거나 삭제할 때마다, 메모 목록이 최신 상태로 유지되도록 합니다. 이렇게 함으로써 사용자는 자신이 작성한 메모를 쉽게 관리할 수 있습니다. 결론 Flutter에서 sqflite패키지를 활용해 데이터를 영구적으로 저장하고 관리하는 방법을 살펴보았습니다. 이를 통해 사용자가 앱을 종료한 후에도 데이터가 유지되는 메모장 앱을 만들 수 있습니다. Flutter와 이러한 패키지들을 사용함으로써, 개발자는 효율적으로 데이터를 관리하고, 사용자에게 더 나은 경험을 제공할 수 있습니다. Flutter로 앱 개발을 시작하는 분들에게 이 글이 도움이 되기를 바랍니다. 읽어주셔서 감사합니다.