본문으로 바로가기
  1. Home
  2. Flutter/Package
  3. Flutter Hive 라이브러리

Flutter Hive 라이브러리

· 댓글개 · Dev_Whale

Hive는 가볍고 빠른 NoSQL DB이다. 배우고 사용하는 데에 있어서 난이도가 높은 편은 아니다.

Hive는 모든 기본 유형의 타입과 List, Map, DateTime, Uint8List를 지원한다. 그리고 other object를 저장하려면 object를 binary form으로 변환하는 TypeAdapter를 등록해야 한다.

Hive PackageHive Docs


프로젝트에 Hive 추가

hivehive_flutterhive_generatorbuild_runner

hive_flutter - flutter에서 쉽게 hive를 만들수 있도록 해준다.

hive_generator - TypeAdapter를 자동으로 만들어 준다. 

build_runner - Dart코드 생성 및 모듈식 컴파일을 위한 빌드 도구

dependencies:
  hive: ^[version]
  hive_flutter: ^[version]

dev_dependencies:
  hive_generator: ^[version]
  build_runner: ^[version]

Based Method

초기화

void main() async {
  await Hive.initFlutter();
  runApp(MyApp());
}

Box 열기 (Open Box)

var box = await Hive.openBox<E>('testBox');

Box 닫기 (Close Box)

var box = await Hive.openBox('myBox');
await box.put('hello', 'world');
await box.close(); // Box 닫기

Box 쓰기 (Write)

var box = Hive.box('myBox');

box.put('name', 'Paul');

box.put('friends', ['Dave', 'Simon', 'Lisa']);

box.put(123, 'test');

box.putAll({'key1': 'value1', 42: 'life'});

Box 읽기 (Read)

var box = Hive.box('myBox');

String name = box.get('name');

DateTime birthday = box.get('birthday');

Box 삭제 (Delete)

exisiting value를 변경하길 원하면, put 메서드를 통해 override 하거나 삭제하면 된다.

box.delete('key'); // 삭제

Custom Objects

  1. TypeAdapter 생성한다.
    1. @HiveType(typeId: 1) typeId는 1과 222사이의 값이 들어간다.
    2. @HiveField(0)에서 field number는 0과 255사이의 값이 들어간다.
    3. 이전 버전의 box와 호환하기 위해서는 typeId를 일관성 있게 만들어야 한다.
    4. box open전에 모든 TypeAdapter를 연결하는 것을 권장한다.
import 'package:hive/hive.dart';

part 'person.g.dart';

@HiveType(typeId: 1)
class Person {
  @HiveField(0)
  String name;

  @HiveField(1)
  int age;

  @HiveField(2)
  List<Person> friends;
}

2. " flutter packages pub run build_runner build "를 터미널에 입력한다.

3. main method에 adapter를 연결한다.

void main() async {
  Hive.registerAdapter(UserAdapter());   // Register Adapter

  var box = await Hive.openBox<User>('userBox');

  box.put('david', User('David'));
}

기존 class를 변경해야 하는 경우

  • 아래의 규칙만 지키면 기존 코드를 건드리지 않고 생성된 adapter를 업데이트할 수 있다.
    • 기존 field number를 변경하면 안된다.
    • 새로운 field를 추가하더라도 old apdater가 작성한 객체를 new adapter가 읽을 수 있다.
      • 새로 추가된 field는 무시하고 parsing 하기 때문이다.
    • field number가 동일하다면 field 이름을 변경할 수 있고 공개에서 비공개로 전환 가능하며 그 반대도 가능하다.
    • field number가 업데이트된 class에서 다시 사용되지 않는 다면 field를 제거할 수 있다.
    • field type 변경은 지원하지 않는다. 새로 만들어야 한다.
    • null safety가 활성화한 후 null를 허용하지 않는 field에서는 defaultValue를 제공해야 한다.
@HiveType(typeId: 2)
class Customer {
  @HiveField(1, defaultValue: 0.0)
  double balance;
}

Write null vs delete 차이점

null 은 없다는 것을 의미하지만 put 메서드로 null를 넣게 된다면 null 이란 값이 존재한다.
delete 메서드로 값을 삭제하면 'key'값을 가진 box 가 없다고 나온다.

var box = await Hive.openBox('writeNullBox');
box.put('key', null);
print(box.containsKey('key')); 결과값 : true
box.delete('key');
print(box.containsKey('key')); 결과값 : false

LazyBox

put() 메서드가 완료가 되지 않으면 get()은 이전 값 또는 값이 존재하지 않는다면 null를 반환한다.

var box = await Hive.openBox('box');

box.put('key', 'value');
print(box.get('key')); // 결과값 : value
===================================================
var lazyBox = await Hive.openLazyBox('lazyBox');

var future = lazyBox.put('key', 'value');
print(lazyBox.get('key')); // 결과값 : null

await future;
print(lazyBox.get('key')); // 결과값 : value

Encrypted box (암호화 box)

저장소에 암호화된 데이터를 저장할 때 사용 (AES-256)

https://docs.hivedb.dev/#/advanced/encrypted_box

 

Hive Docs

 

docs.hivedb.dev

질문

질문내용 : ListView 안에 있는 ValueListenableBuilder 위젯이 변하지 않지만 ValueListenableBuilder 안에 있는 ListView 위젯은 변한다. 왜?

https://github.com/hivedb/hive/issues/878

 

Why doesn't the Value Listenable Builder value in ListView change? · Issue #878 · hivedb/hive

Question I think the Value Listenable Builder widget in ListView should change. But that's not the case. Can you tell me why you did that? I'd really appreciate it if you could answer. Plea...

github.com

ValueListenableBuilder

원하는 box의 값이 변화를 수시로 refresh 하고 싶다면 이 위젯을 사용하자. box의 특정 key의 값만 listenable 할 수 있다.

ValueListenableBuilder(
  valueListenable: box.listenable(), // box.listenable() = Hive.Box('HiveBox').listenable(),
  builder: (context, box, widget) {
    return ListView.builder(
        shrinkWrap: true,
        itemCount: Hive.box('HiveBox').keys.length,
        itemBuilder: (context, index) {
          var key = Hive.box('HiveBox').keyAt(index);
          var value = Hive.box('HiveBox').getAt(index);
          return Padding(
            padding: const EdgeInsets.all(10),
            child: Card(
              shape: shape,
              elevation: 0,
              child: Padding(
                padding: const EdgeInsets.all(8),
                child: Column(
                  children: [Text('key : $key'), Text('value : $value')],
                ),
              ),
            ),
          );
        });
  },
),

특정키 만 Listenable 하기

ValueListenableBuilder<Box>(
  valueListenable: Hive.box('settings').listenable(keys: ['firstKey', 'secondKey']),
  builder: (context, box, widget) {
    // build widget
  },
)

 

Hive를 사용할 때와 사용하지 않을 때

https://docs.hivedb.dev/#/best-practices/when_to_use_hive

 

Hive Docs

 

docs.hivedb.dev

💬 댓글 개
이모티콘창 닫기
울음
안녕
감사해요
당황
피폐

이모티콘을 클릭하면 댓글창에 입력됩니다.