플러터에서 SQLite를 이용해 데이터베이스를 만들어보았다.
플러터에선 sqflite라는 패키지를 제공해 SQLite를 사용할 수 있게 해준다.
pubspec.yaml에 SQLite 사용을 위한 sqflite와 내부 저장소 사용을 위한 path 패키지를 추가했다.
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
sqflite: ^2.0.0+3
path: ^1.8.0
데이터베이스 구조를 만들었다.
lib 폴더에 todo.dart 파일을 만들고 코드를 다음과 같이 작성하였다.
class Todo {
String? title;
String? content;
int? active;
int? id;
Todo({this.title, this.content, this.active, this.id});
Map<String, dynamic> toMap(){
return {
'id' : id,
'title' : title,
'content' : content,
'active' : active,
};
}
}
데이터베이스에 넣을 데이터를 title, content, active, id 로 구성하였다. 각각 제목, 내용, 완료여부, 순번을 나타낸다.
플러터의 sqflite 패키지는 데이터를 Map 형태로 다루기때문에 데이터를 Map 형태로 반환해주는 toMap() 함수를 정의하였다.
main.dart 파일을 다음처럼 수정하였다.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: DatabaseApp()
);
}
}
class DatabaseApp extends StatefulWidget {
State<StatefulWidget> createState() {
return _DatabaseApp();
}
}
class _DatabaseApp extends State<DatabaseApp>{
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Database Example'),),
body: Container(),
floatingActionButton: FloatingActionButton(
onPressed: () async {
final todo = await Navigator.of(context).pushNamed('/add');
},
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}
StatefulWidget을 상속받는 DatabaseApp 클래스를 작성해 home으로 지정하였다.
DatabaseApp 클래스에 데이터베이스에서 가져온 할 일 목록을 보여주는 UI를 구현하고,
앱이 시작될 때 MyApp 클래스에서 데이터베이스를 만들어 DatabaseApp 클래스에 전달하도록 만들어보았다.
main.dart 파일의 MyApp 클래스에 데이터베이스를 생성하는 initDatabase() 함수를 만들었다.
데이터베이스 함수를 사용하는데 필요한 패키지들도 import 하였다.
import 'package:flutter/material.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: DatabaseApp()
);
}
Future<Database> initDatabase() async{
return openDatabase(
join(await getDatabasesPath(), 'todo_database.db'),
onCreate: (db, version) {
return db.execute(
"CREATE TABLE todos(id INTEGER PRIMARY KEY AUTOINCREMENT, "
"title TEXT, content TEXT, active INTEGER)"
);
},
version: 1
);
}
}
initDatabase() 함수는 데이터베이스를 열어서 반환해준다.
데이터베이스는 getDatabasePath() 함수가 반환하는 경로에 todo_database.db라는 파일로 저장되어 있으므로 이 파일을 불러와 반환해준다.
todo_database.db 파일에 테이블이 없다면 onCreate를 이용해 새로운 테이블을 만든다.
build() 함수에서 initDatabase() 함수를 호출하도록 코드를 추가했다
Widget build(BuildContext context) {
Future<Database> database = initDatabase();
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
initialRoute: '/',
routes: {
'/' : (context) => DatabaseApp(database),
'/add' : (context) => AddTodoApp(database)
},
);
}
routes를 이용해 경로를 지정하였고,
각 클래스를 호출하면서 database 객체를 전달하도록 만들었다.
build() 함수에서 DatabaseApp 클래스를 호출할 때 database 객체를 전달했으므로 DatabaseApp 클래스를 다음처럼 수정했다.
class DatabaseApp extends StatefulWidget {
final Future<Database> db;
DatabaseApp(this.db);
...
routes에서 /add로 경로를 지정한 AppTodoApp 클래스를 작성하였다.
addTodo.dart 파일을 만들고 그 안에 StatefulWidget을 상속받는 AddTodoApp 클래스를 작성하였다.
이 클래스에서는 데이터를 입력해 테이블에 추가하는 화면을 만들 예정이다.
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'todo.dart';
class AddTodoApp extends StatefulWidget {
final Future<Database> db;
AddTodoApp(this.db);
State<StatefulWidget> createState() {
return _AddTodoApp();
}
}
class _AddTodoApp extends State<StatefulWidget>{
void initState() {
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Todo 추가'),),
body: Container(
child: Center(
child: Column(
children: <Widget>[],
),
),
),
);
}
}
이것으로 데이터베이스를 사용할 준비를 마쳤다.
다음부터 데이터베이스를 이용해 생성, 읽기, 갱신, 삭제 기능을 추가해보겠다.
sqflite: ^2.0.0+3
데이터베이스 구조 정의를 위한 클래스를 만든다.
sqflite 패키지는 데이터를 Map 형태로 다룬다.
openDatabase() 함수로 지정된 위치의 데이터베이스를 연다.
getDatabasesPath() 함수로 데이터베이스가 저장되는 기본 위치 경로를 얻는다
테이블이 없다면 onCreate()로 새 테이블을 만든다.
return openDatabase(
join(await getDatabasesPath(), 'todo_database.db'),
onCreate: (db, version) {
return db.execute(
"CREATE TABLE todos(id INTEGER PRIMARY KEY AUTOINCREMENT, "
"title TEXT, content TEXT, active INTEGER)"
);
},
version: 1
);