Hive가 대체 머야.... 먼데 자꾸 쓰냐...
Developer English 앱 만들면서
오답노트 기능 저장할 때 Hive를 썼는데,
사실 그때도 "일단 하라니까 쓴다" 수준이었지
Hive가 정확히 뭔지,
왜 다른 것들 두고 이걸 썼는지는
제대로 몰랐어요.
이번 기회에 제대로 정리해보려고요.
1. Hive는 한마디로 - Flutter용 로컬 저장소
Hive는
Flutter/Dart 앱 안에서
데이터를 기기에 직접 저장하는 NoSQL 데이터베이스예요.
서버 없이, 인터넷 연결 없이
앱 안에서 데이터를 저장하고 불러올 수 있게 해주는 도구죠.
제 앱의 오답노트가 인터넷을 안 켜도 예전에 틀렸던 문제를 계속 보여주는 게
바로 이 Hive 덕분이었어요.
2. 이름이 왜 Hive(벌집)일까?
이게 은근 개념 이해에 도움이 되는 부분인데요,
Hive의 핵심 구조가 진짜 벌집처럼 짜여있어요.
제 오답노트 기능으로 치면,
wrongNotesBox라는 Box(벌집 칸) 하나를 만들어서
그 안에 "문제 ID → 오답 정보" 형태로
꿀(데이터)을 차곡차곡 채워넣은 거였어요.
3. 왜 SQLite 안 쓰고 Hive를 썼을까?
Flutter에서 로컬 저장소 선택지가 여러 개 있는데, 각각 쓰임새가 달라요.
제일 크게 와닿았던 차이는 이거였어요.
SQLite는
SQL 쿼리문을 따로 배워서 써야 하는데,
Hive는
그냥 Dart 클래스 객체를 그대로 저장하고 꺼내 쓸 수 있어요.
오답노트처럼
"문제, 내 답, 정답, 틀린 날짜"를 담은 객체 하나를 통째로 저장했다가
그대로 꺼내 쓰는 구조라
SQL 없이 Dart 코드만으로 끝나는 Hive가 훨씬 편했어요.
게다가 순수 Dart로 만들어져서 네이티브 의존성이 없다 보니 속도도 꽤 빨랐고요.
4. 실제로 어떻게 쓰는지 (제 오답노트 코드 기준)
4-1. 초기화
// main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Hive.initFlutter();
Hive.registerAdapter(WrongNoteAdapter()); // 내가 만든 모델의 어댑터 등록
await Hive.openBox<WrongNote>('wrongNotesBox');
runApp(MyApp());
}
4-2. 모델 클래스에 어댑터 붙이기
@HiveType(typeId: 0)
class WrongNote extends HiveObject {
@HiveField(0)
String question;
@HiveField(1)
String myAnswer;
@HiveField(2)
String correctAnswer;
WrongNote({required this.question, required this.myAnswer, required this.correctAnswer});
}
이 @HiveType, @HiveField 어노테이션 보고
처음엔 "이게 왜 필요하지?" 싶었는데,
Hive는 Dart 객체를 그대로 저장할 수 있게 바이너리로 변환해서 저장하거든요.
근데 Dart는
원래 리플렉션(런타임에 클래스 구조 읽는 기능)을 지원 안 해서,
어떤 필드를 몇 번째 자리에 저장할지
미리 알려주는 역할을 이 어노테이션이 해주는 거였어요.
그리고 이 어노테이션 기반으로 build_runner가
실제 변환 코드(*.g.dart 파일)를 자동 생성해줘요.
4-3. 저장 / 조회 / 삭제
final box = Hive.box<WrongNote>('wrongNotesBox');
// 저장
box.add(WrongNote(question: "...", myAnswer: "...", correctAnswer: "..."));
// 전체 조회
List<WrongNote> allNotes = box.values.toList();
// 삭제
await box.deleteAt(0);
SQL 쿼리 한 줄 없이,
그냥 Dart 리스트 다루듯이 쓸 수 있다는 게 진짜 편했어요.
5. 헷갈렸던 부분 - Provider랑은 무슨 관계?
제 앱에서 Provider랑 Hive를 같이 쓰다 보니
처음엔 둘이 하는 일이 겹치는 줄 알았는데,
역할이 완전히 달라요.
- Hive: 데이터를 기기에 영구 저장하는 역할 (앱을 껐다 켜도 남아있음)
- Provider: 화면들 사이에서 상태를 실시간으로 공유·전달하는 역할 (앱이 켜져있는 동안만)
그래서 실제 흐름은
"Hive에서 데이터 불러오기 → Provider한테 그 데이터를 넘겨서
여러 화면이 실시간으로 반영하도록 관리" 순서였어요.
둘이 경쟁 관계가 아니라 저장(Hive)과 화면 반영(Provider)으로
역할 분담을 하는 거였더라고요.
오늘의 정리
- Hive는 Flutter/Dart용 로컬 NoSQL 데이터베이스 - 서버나 인터넷 없이 기기에 데이터 저장
- Box(벌집 칸)라는 단위로 데이터를 저장하고, 그 안에 key-value 형태로 값이 들어감
- SQL 쿼리 없이 Dart 객체를 그대로 저장·조회할 수 있어서 편함
@HiveType/@HiveField는 Dart 객체를 바이너리로 변환하기 위한 설계도 역할- Hive(저장) + Provider(화면 공유)는 경쟁이 아니라 역할 분담 관계
이번에 정리하면서 느낀 건데,
저처럼 일단 코드 돌아가니까 계속 갖다 쓰다가
나중에서야 "이게 대체 뭐였지" 하고
되짚어보는 경우 은근 많은 것 같아요.
다음엔 Provider 자체도 한 번 제대로 파봐야겠어요 🍑
댓글 없음:
댓글 쓰기