Hive是个 ....(此处忽略一万个字)的数据库。总之性能很好,下面是该库提供的一个对比图。
废话不多说,直接上手使用。Let's go.
1.引入依赖:
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
hive: ^2.0.4
hive_flutter: ^1.1.0
path_provider: ^2.0.2
dev_dependencies:
flutter_test:
sdk: flutter
hive_generator: 1.1.0
build_runner: 2.1.1
2.初始化 在main方法里初始化Hive,然后注册adapter。 然后使用Hive.openBox方法打开contacts表,以备使用。
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:learn/model/contact.dart';
import 'contact_page.dart';
Future<void> main() async {
await Hive.initFlutter();
Hive.registerAdapter(ContactAdapter());
await Hive.openBox<Contact>('contacts');
runApp(MyApp());
}
MyApp的代码很简单,没什么可说的。
@override
Widget build(BuildContext context) {
return MaterialApp(
//enableLog: true,
title: 'hive',
debugShowCheckedModeBanner: false,
theme: ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.blue,
primaryColor: Colors.blue,
fontFamily: 'roboto',
),
home: ContactPage());
}
这个时候你可能会有报错,因为你需要一个实体类Contact。ok,我们继续。
3.新建一个Contact实体类。字段支持嵌套对象,就跟int String 没啥区别,只需要重复此过程再创建一个实体类即可。
注意别忘了part 'contact.g.dart';
import 'package:hive/hive.dart';
part 'contact.g.dart';
@HiveType(typeId: 0)
class Contact extends HiveObject {
@HiveField(0)
final String name;
@HiveField(1)
final int age;
Contact(this.name, this.age);
}
然后运行以下指令,build_runner插件会自动创建contact.g.dart文件。
flutter packages pub run build_runner build --delete-conflicting-outputs
4.好了,到了ContactPage页面
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/adapters.dart';
import 'model/contact.dart';
import 'new_contact_form.dart';
const String contactsBoxName = "contacts";
class ContactPage extends StatelessWidget {
const ContactPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Hive demo'),
),
body: Column(
children: [Expanded(child: _buildListView()), NewContactForm()],
),
);
}
Widget _buildListView() {
return ValueListenableBuilder(
valueListenable: Hive.box<Contact>(contactsBoxName).listenable(),
builder: (context, Box<Contact> box, _) {
if (box.values.isEmpty)
return Center(
child: Text("No contacts"),
);
return ListView.builder(
itemCount: box.values.length,
itemBuilder: (context, int index) {
Contact currentContact = box.getAt(index)!;
return ListTile(
title: Text('${currentContact.name}'),
subtitle: Text('${currentContact.age}'),
trailing:
ButtonBar(mainAxisSize: MainAxisSize.min, children: [
IconButton(
onPressed: () {
box.putAt(
index,
Contact('${currentContact.name}*',
currentContact.age + 1));
},
icon: Icon(Icons.refresh),
),
IconButton(
onPressed: () {
box.deleteAt(index);
},
icon: Icon(Icons.delete),
),
]),
);
});
});
}
}
Hive的增删改查方法也很简单,就不说了 对应put、delete、get,没有update,需要更新直接put就行。
ValueListenableBuilder是一个特色的东西,是个响应式的UI控件,当数据改变的时候会自动更新。
5.如果需要大量数据hive提供了lazyBox
var lazyBox = await Hive.openLazyBox('myLazyBox');
var value = await lazyBox.get('lazyVal');
如果是已经打开过的lazybox则
var lazyBox = Hive.lazyBox('myLazyBox');
6.整理压缩
Hive is an append-only data store. When you change or delete a value, the change is written to the end of the box file. Sooner or later, the box file uses more disk space than it should. Hive may automatically "compact" your box at any time to close the "holes" in the file.
在关闭时应该先调用compact以压缩。
var box = Hive.box('contacts');
await box.compact();
await box.close();
还可以设置自动压缩的条件
var box = await Hive.openBox('contacts', compactionStrategy: (entries, deletedEntries) {
return deletedEntries > 50;
});
compactionStrategy 会在超过50个键值对被重写或删除时进行压缩。
最后一个警告
** NEVER access a box from the compaction strategy.**