플러터에서 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()
함수를 호출하도록 코드를 추가했다
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)
},
);
}
Widget
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
);