Isar?
Isar: SQLite를 백엔드로 쓰는 로컬 DB. 클래스를 저장가능한 형태로 자동변환해줘서 편리함.
Isar Quickstart
- Add dependencies
(인터페이스를 위한 패키지)
flutter pub add isar isar_flutter_libs path_provider
(코드를 자동생성하는 패키지)
flutter pub add -d isar_generator build_runner
isar_generator
, build_runner
는 그냥 코드 생성기이기 때문에 dev dependency라는 점.
만약 모델을 별도 패키지에서 관리한다면 그 패키지에서만 이 두 패키지를 추가해서 사용하면 됨.
- Annotate classes
import 'package:isar/isar.dart';
part 'user.g.dart'; // *
@collection // *
class User {
Id id = Isar.autoIncrement; // *; you can also use id = null to auto increment
String? name;
int? age;
}
*
표시한 줄은 반드시 필요함.
import 'package:equatable/equatable.dart';
import 'package:isar/isar.dart';
part 'user.g.dart';
@Collection(inheritance: false) // `equatable` 패키지를 쓰고싶으면 상속을 무시하는 annotation을 써야한다.
class User extends Equatable {
const User({
required this.id,
this.isarId = Isar.autoIncrement,
this.email,
this.name,
this.photo,
});
final Id isarId; // Isar는 필드 이름에 상관없이 `Id` 타입만 본다.
final String id;
final String? name;
final int? age;
@ignore // 저장하지 않는 필드는 @ignore를 쓴다.
static const empty = User(id: '');
@ignore
bool get isEmpty => this == User.empty;
@ignore
bool get isNotEmpty => this != User.empty;
@override
@ignore
List<Object?> get props => [email, id, name, photo];
}
equatable
도 함께 쓸 수 있다.
- Run code generator
$ dart run build_runner build
user.g.dart
파일이 만들어진다.
- Open Isar instance
final dir = await getApplicationDocumentsDirectory(); // path_provider 패키지 함수
final isar = await Isar.open(
[UserSchema],
directory: dir.path,
);
user.g.dart
에 정의된 UserSchema
를 전달한다.
- Write and read
final newUser = User()..name = 'Jane Doe'..age = 36;
await isar.writeTxn(() async {
await isar.users.put(newUser); // insert & update
});
final existingUser = await isar.users.get(newUser.id); // get
await isar.writeTxn(() async {
await isar.users.delete(existingUser.id!); // delete
});
그러나…
나는 Business Logic이나 API를 별도 패키지에서 관리하고싶었는데, 여기서 반드시 Isar에 의존해야했다. 그러나 Isar는 unit test가 안된다는 단점이 있었다. 그래서 포기했다. 구글에 검색하니 이곳에서 방법을 찾을 수 있었는데 간단한 것 같지 않았다.
SQFlite를 쓰자니 이건 웹에서 지원이 안된다.