Dart package Floor

SQLite 的 ORM package

https://pub.dev/packages/floor

看起來是走 Entity pattern 那一系的。覺得可以直接用 class 去定義 schema 好像不錯

Entity class

代表一筆資料的 class,也可以說是 table 的欄位。

1
2
3
4
5
6
7
8
9
10
11
12
13
// person.dart

import 'package:floor/floor.dart';

@entity
class Person {
@primaryKey
final int id;

String name;

Person(this.id, this.name);
}

DAO (Data Access Object)

負責 access 底層 SQLite database。得是 abstract class,method 必須 return FutureStream。並且用 annotation 標示 CRUD 的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// person_dao.dart

import 'package:floor/floor.dart';

import 'person.dart';

@dao
abstract class PersonDao {
@Query('SELECT * FROM Person')
Future<List<Person>> findAllPersons();

@Query('SELECT * FROM Person WHERE id = :id')
Future<Person> findPersonById(int id);

@insert
Future<void> insertPerson(Person person);

@update
Future<void> updatePerson(Person person);

@delete
Future<void> deletePerson(Person person);
}

Database

要是一個 extend FloorDatabase 的 abstract class。

在 class signature 要加 @Database(),並且要把 entity 加進其中 entities attribute 中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// database.dart

import 'dart:async';
import 'package:floor/floor.dart';
import 'package:sqflite/sqflite.dart' as sqflite;

import 'person_dao.dart';
import 'person.dart';

part 'database.g.dart'; // the generated code will be there

@Database(version: 1, entities: [Person])
abstract class AppDatabase extends FloorDatabase {
PersonDao get personDao;
}

import 後要記得加 part 'database.g.dart'

接著執行 flutter packages pub run build_runner buil 就會產生 database.g.dart。如果要在 database 改變的時候自動 build 出 database.g.dart,可以下 flutter packages pub run build_runner watch

最後是使用 database:

1
2
3
4
5
6
7
8
9
10
// database.db 是 db 的 file name
final database = await $FloorAppDatabase.databaseBuilder('database.db').build();
final personDao = database.personDao;

final person = Person(1, 'John');
await personDao.insertPerson(person);

final result = await personDao.findPersonById(1);

print(result.name);