Hive — лако NoSQL складиште за Flutter које ради без изворног кода. За разлику од SQLite или Firebase, Hive не захтева повезивање изворних библиотека и ради искључиво преко Dart-а. Према Pub.dev, 2024, Hive је преузет преко 10 милиона пута и користи се у сваком трећем Flutter пројекту где је потребно локално складиштење података без серверске инфраструктуре.
Главне карактеристике
Hive — је NoSQL база података написана у потпуности у Dart-у која не захтева изворне библиотеке. Направио је Simon Leiter 2019. године као алтернативу SQLite-у за Flutter пројекте. Hive чува податке у бинарном формату .hive, који је оптимизован за брзо читање и писање на мобилним уређајима. .hive формат користи прилагођену шему серијализације, где сваки тип података има свој бајтни префикс, што омогућава читање датотеке без претходног знања о шеми — за разлику од Protocol Buffers или FlatBuffers.
Основна идеја Hive-а — максимална једноставност. База података не захтева иницијализацију изворних погона, не укључује SQL парсер и не користи рефлексију. Све операције су директни позиви Dart функција са бинарном серијализацијом преко WriteBuffer и ReadBuffer.
Према анкети Flutter Community (2023), Hive је у топ 5 најчешће коришћених пакета за складиштење података у Flutter-у, одмах иза shared_preferences по популарности, али га надмашује по функционалности и брзини.
Hive користи концепт Box — аналогон табеле у релационим базама података. Сваки Box је датотека на диску са скупом парова кључ-вредност. Кључ може бити int или String, вредност — било који примитивни тип, листа, Map или прилагођени објекат преко TypeAdapter. Box-ови су изоловани једни од других и отварају се независно.
Hive не захтева платформске канале (platform channels). То значи да ради исто на Android, iOS, Web, macOS, Windows и Linux без додатног подешавања. За пројекте усмерене на веб компилацију, Hive остаје једино лако NoSQL решење — SQLite не ради у прегледачу. Истовремено, Hive користи IndexedDB као позадину за веб, што обезбеђује перзистентност података и у окружењу прегледача.
Hive серијализује податке у бинарни формат при писању и десеријализује при читању. Унутрашњи механизам се заснива на BinaryWriter и BinaryReader, који пакују податке у компактне бајтне низове. Величина складишта на диску је у просеку 2–3 пута мања од JSON приказа истих података.
При отварању Box-а, Hive учитава целу датотеку у RAM меморију. То обезбеђује велику брзину читања (микросекунде), али намеће ограничење величине података: препоручује се чување највише 50–100 MB по једном Box-у. За веће количине користите LazyBox — лењо учитавање записа са диска.
Hive ради једнонитно у изолацији Dart-изолата. Операције писања се извршавају синхроно са закључавањем датотеке. За асинхрони приступ користите Hive.openBox() са await. Конкурентни приступ из више изолата није директно подржан — за то је потребан посебан механизам синхронизације.
Hive заузима нишу између SharedPreferences и SQLite. Сложенији је од SharedPreferences (подржава прилагођене објекте), али једноставнији од SQLite-а (не захтева SQL упите). Упоредимо кључне карактеристике.
| Карактеристика | Hive | SharedPreferences | SQLite |
|---|---|---|---|
| Типови података | Било који (преко TypeAdapter) | Само примитиви | SQL типови |
| Брзина читања | ~30 000 ops/s | ~5 000 ops/s | ~2 000 ops/s |
| Изворни код | Није потребан | Потребан (Android) | Потребан |
| Веб подршка | Да | Не | Не |
| Сложеност | Ниска | Минимална | Средња |
| Реактивност | WatchBox | Не | Преко ORM |
Hive је оптималан за мале количине података: подешавања апликације, кеш API одговора, локални ред синхронизације, омиљени и историја прегледа. Ако подаци не прелазе 50 MB и не захтевају релационе упите — Hive је бржи и једноставнији од SQLite-а.
Hive не подржава упите са филтрирањем по више поља, JOIN, агрегатне функције. Ако су вам потребни сложени упити типа “изабери све задатке за данас са приоритетом изнад 3” — користите SQLite са drift или floor. Hive такође није погодан за чување преко 100 MB података због учитавања у меморију.
Hive почиње са иницијализацијом и отварањем Box-а. Испод су приказане основне операције за типичан сценариј — чување листе задатака у Flutter апликацији. Сви примери раде без изворних платформских позива.
Пре коришћења Hive-а потребно је позвати Hive.initFlutter() у main функцији. Затим отворити Box преко Hive.openBox() — резултат ће бити инстанца Box спремна за читање и писање.
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
void async main() {
await Hive.initFlutter();
final settingsBox = await Hive.openBox('settings');
runApp(MyApp());
}
Box пружа методе put, get, delete и садржи итератор за прелазак преко свих записа. Кључеви и вредности се типизирају преко генерика — подразумевано Box<dynamic> дозвољава било које типове, али се препоручује навођење конкретног типа.
// Уписивање података
final box = await Hive.openBox<String>('tasks');
await box.put('task_1', 'Купи производе');
// Читање
final task = box.get('task_1');
// Сви кључеви
final allTasks = box.values.toList();
// Брисање
await box.delete('task_1');
// Чишћење Box-а
await box.clear();
WatchBox — проширење Box-а које обавештава претплатнике о променама. У Flutter-у се ово интегрише са ValueListenableBuilder: при промени било које вредности у Box-у, виџет се аутоматски обнавља без позивања setState.
final watchBox = await Hive.openBox('settings');
// У виџету
ValueListenableBuilder(
valueListenable: watchBox.listenable(),
builder: (context, box, _) {
final counter = box.get('counter') ?? 0;
return Text('Бројач: $counter');
},
)
TypeAdapter — Hive-ов механизам за серијализацију прилагођених Dart објеката. Адаптер описује како претворити објекат у бинарни формат (write) и назад (read). За разлику од json_serializable, TypeAdapter не захтева рефлексију и ради брже.
Адаптер имплементира интерфејс TypeAdapter
// Модел података
class Task {
final String title;
final bool isCompleted;
Task({required this.title, this.isCompleted = false});
}
// TypeAdapter
class TaskAdapter extends TypeAdapter<Task> {
@override
final int typeId = 0;
@override
Task read(BinaryReader reader) {
return Task(
title: reader.readString(),
isCompleted: reader.readBool(),
);
}
@override
void write(BinaryWriter writer, Task obj) {
writer.writeString(obj.title);
writer.writeBool(obj.isCompleted);
}
}
За пројекте са великим бројем модела, Hive обезбеђује hive_generator и build_runner. Анотација @HiveType на класи и @HiveField на пољима генерише адаптер аутоматски. Ово је згодно када модел садржи 10+ поља — ручно писање read/write постаје напорно.
Hive обавља читање из меморије, а не са диска, што даје брзину до 30 000 операција у секунди. За оптимизацију: отворите Box једном и поново га користите у целој апликацији, не позивајте openBox поново. Користите Hive.box() (синхрони гетер) након иницијализације — враћа већ отворени Box без креирања нове инстанце.
Hive се лако интегрише са популарним Flutter менаџерима стања. За Provider користите ChangeNotifierProvider који чита податке из Box-а при иницијализацији и ажурира се преко listenable. За Riverpod је погодан StreamProvider претплаћен на WatchBox. Таква комбинација даје реактивно ажурирање UI при свакој промени података у Hive-у без ручног позивања setState. У типичном Flutter пројекту оваква архитектура омогућава синхронизацију стања између екрана без глобалног синглтона.
Често постављана питања
Hive ради у чистом Dart-у, па се може користити у било ком Dart пројекту: серверском (Dart VM), конзолном или AngularDart. За Flutter се додатно повезује hive_flutter са иницијализацијом путања складиштења.
Hive подржава AES-256 шифровање кроз параметар encryptionKey при отварању Box-а. Кључ мора бити низ од 32 бајта. Шифровани Box се не може читати без кључа — подаци су заштићени на нивоу датотеке.
Isar — наследник Hive-а од истог аутора (Simon Leiter). Isar је бржи, подржава индексе, релације и сложене упите. Међутим, Hive остаје актуелан за једноставне сценарије где нису потребне релационе могућности Isar-а и за пројекте где је минимална зависност важна.
Hive нема уграђене миграције. Ако се структура TypeAdapter променила, стари подаци се неће десеријализовати. Решење: повећајте typeId адаптера и напишите ручну миграцију у коду или користите delete за стари кључ пре писања новог.
Hive учитава Box у меморију у целости. Препоручени лимит је 50–100 MB по једном Box-у. При прекорачењу могућа су кашњења при отварању Box-а и повећана потрошња RAM-а. За веће количине користите више Box-ова или LazyBox са лењим учитавањем.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође