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 Future
或 Stream
。並且用 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);
|