Cách sử dụng Hive đơn giản nhưng hiệu quả mà có thể bạn chưa biết
Hive
là thư viện của Flutter
, một công cụ lưu trữ dữ liệu trong bộ nhớ điện thoại. Bài viết này hướng đến những người đã biết cơ bản về Hive
, nếu chưa biết Hive
là gì có thể tham khảo tại đây . Hive
có nhiều ưu điểm như tốc độ đọc ghi rất nhanh, thiết lập và sử dụng dễ dàng,…
Tuy nhiên, khi muốn lưu trữ một kiểu dữ liệu đặc biệt do chính bạn xác định, bạn phải đăng ký và tạo một trình cập nhật như dưới đây
mport 'package:hive/hive.dart';
part 'person.g.dart';
@HiveType(typeId: 1)
class Person {
@HiveField(0)
String name;
@HiveField(1)
int age;
}
Cách này gây ra rất nhiều bất tiện, khi chúng ta phải quản lý typeId
cũng như phải viết rất nhiều code soạn sẵn mỗi khi muốn tạo một custom type
. Có cách nào khác đơn giản và sạch sẽ hơn không? Câu trả lời là có.
Bài toán : Tạo cách lưu và đọc đối tượng của 2 lớp Person
và User
trong cơ sở dữ liệu cục bộ. LớpPerson
bao gồm name
và age
, lớp Person
dùng bao gồm userId
.
Bước 1: Tạo một lớp trừu tượng LocalEntity
abstract class LocalEntity {
final String key;
LocalEntity(this.key);
}
Bước 2: Đối với các lớp cần lưu trữ cục bộ, hãy triển khai lớp LocalEntity
này
part 'person.g.dart';
// don't forget to add fromJson and toJson
@JsonSerializable()
class Person implements LocalEntity{
final String id;
final String name;
final int age;
Person({
required this.id,
required this.name,
required this.age,
});
factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);
Map<String, dynamic> toJson() => _$PersonToJson(this);
// Choose one of person field to be the key
// this key will be used to save to local database
@override
String get key => id;
}
NOTE: Làm tương tự với lớp User
Bước 3: Tạo một lớp LocalEntityRepository
Lớp này chịu trách nhiệm liên lạc với Hive
để đọc và ghi User
và Person
. Trước hết hãy xem repo này ghi dữ liệu như thế nào (chúng ta sẽ quay lại phần ghi dữ liệu sau)
class LocalEntityRepository {
final String boxName;
Future<void> createOrUpdate(LocalEntity data) async {
await Hive.box<String>(boxName)
.put(data.key, jsonEncode(data));
}
Future<void> deleteData(String id) async {
Hive.box<String>(boxName).delete(id);
}
}
Bước 4: Chỉ cần sử dụng nó
Bạn có thể tạo và quản lý localEntityRepository
ở bất cứ đâu. Tôi sẽ đưa ra một ví dụ về trường hợp sử dụng phổ biến trong bộ điều khiển. Để nội dung bài viết không bị lan truyền, mình sẽ không sử dụng Dependence Insert
mà chỉ khởi tạo đối tượng một cách bình thường.
- Đừng quên mở hộp trước khi sử dụng
class Controller {
final personRepo = LocalEntityRepository("person");
savePerson(Person person) {
// add try/catch as you want
personRepo.createOrUpdate(person);
}
}
Rất đơn giản phải không? Như vậy là chúng ta đã ghi dữ liệu cục bộ rồi, việc tiếp theo là đọc dữ liệu từ Hive
Bước 5: Đọc dữ liệu
Hãy thêm 2 hàm sau vào LocalEntityRepository
class LocalEntityRepository {
//...
List<T> getAllEntities<T extends LocalEntity>() {
final data = Hive.box<String>(boxName).values.map((e) {
return LocalEntity.fromJson(T, Map<String, dynamic>.from(jsonDecode(e)));
}).toList();
return List<T>.from(data);
}
T? getEntity<T extends LocalEntity>(String id) {
final dataLocal = Hive.box<String>(boxName).get(id);
if (dataLocal == null) return null;
return LocalEntity.fromJson(T, Map<String, dynamic>.from(jsonDecode(dataLocal))) as T;
}
}
Bạn sẽ gặp lỗi vì LocalEntity
không có hàm fromJson
tĩnh, đó là lúc chúng ta sửa lớp LocalEntity
. Thêm chức năng xuất xưởng từ Json
như bên dưới
abstract class LocalEntity {
final String key;
LocalEntity(this.key);
factory LocalEntity.fromJson(Type type, Map<String, dynamic> e) {
switch (type) {
case Person:
return Person.fromJson(e);
case User:
return User.fromJson(e);
default:
throw Exception();
}
}
}
Thế là xong, bây giờ chúng ta hãy đọc dữ liệu
class Controller {
final personRepo = LocalEntityRepository("person");
List<Person> getAllPerson() {
final persons = personRepo.getAllEntities<Person>();
return persons;
}
}
Bình luận