Hive — könnyű NoSQL tároló Flutterhez, amely natív kód nélkül működik. Ellentétben az SQLite-tal vagy Firebase-szel, a Hive nem igényli natív könyvtárak csatlakoztatását, és kizárólag Dart-on keresztül működik. A Pub.dev, 2024 adatai szerint a Hive-t több mint 10 milliószor töltötték le, és minden harmadik Flutter projektben használják, ahol helyi adattárolásra van szükség szerverinfrastruktúra nélkül.
Főbb pontok
A Hive — egy NoSQL adatbázis, amely teljes egészében Dart-ban íródott, és nem igényel natív könyvtárakat. Simon Leiter hozta létre 2019-ben az SQLite alternatívájaként Flutter projektekhez. A Hive bináris .hive formátumban tárolja az adatokat, amely optimalizálva van gyors olvasásra és írásra mobileszközökön. A .hive formátum egyedi szerializációs sémát használ, ahol minden adattípusnak saját bájt előtagja van, lehetővé téve a fájl olvasását a séma előzetes ismerete nélkül — ellentétben a Protocol Buffers-szal vagy FlatBuffers-szel.
A Hive fő ötlete — maximális egyszerűség. Az adatbázis nem igényli natív motorok inicializálását, nem tartalmaz SQL elemzőt és nem használ reflexiót. Minden művelet közvetlen Dart függvényhívás bináris szerializációval a WriteBuffer és ReadBuffer segítségével.
A Flutter Community (2023) felmérése szerint a Hive a top 5 leggyakrabban használt csomag között van adattárolásra Flutter-ben, népszerűségben csak a shared_preferences mögött, de funkcionalitásban és sebességben felülmúlja azt.
A Hive a Box koncepciót használja — a relációs adatbázisok táblájának analógját. Minden Box egy fájl a lemezen kulcs-érték párok halmazával. A kulcs lehet int vagy String, az érték — bármilyen primitív típus, lista, Map vagy egyedi objektum a TypeAdapter segítségével. A Box-ok el vannak szigetelve egymástól és egymástól függetlenül nyílnak meg.
A Hive nem igényel platformcsatornákat (platform channels). Ez azt jelenti, hogy ugyanúgy működik Android, iOS, Web, macOS, Windows és Linux rendszeren további konfiguráció nélkül. A webes fordításra irányuló projektek számára a Hive marad az egyetlen könnyű NoSQL megoldás — az SQLite nem működik a böngészőben. Ugyanakkor a Hive az IndexedDB-t használja backendként a webhez, ami biztosítja az adatok perzisztenciáját a böngésző környezetében is.
A Hive az adatokat bináris formátumba szerializálja íráskor és deszerializálja olvasáskor. A belső mechanizmus a BinaryWriter és BinaryReader alapokon nyugszik, amelyek az adatokat kompakt bájt tömbökbe csomagolják. A tároló mérete a lemezen átlagosan 2-3-szor kisebb, mint ugyanazon adatok JSON reprezentációja.
A Box megnyitásakor a Hive a teljes fájlt betölti a RAM-ba. Ez nagy olvasási sebességet (mikroszekundumok) biztosít, de korlátozza az adatok méretét: ajánlott legfeljebb 50-100 MB-ot tárolni egy Box-ban. Nagyobb mennyiségekhez használja a LazyBox-ot — a rekordok lusta betöltését a lemezről.
A Hive egyszálúan működik a Dart-izolátum elkülönítésében. Az írási műveletek szinkron módon, fájlzárolással történnek. Aszinkron hozzáféréshez használja a Hive.openBox()-ot await-tel. A párhuzamos hozzáférés több izolátumból nem támogatott közvetlenül — ehhez külön szinkronizációs mechanizmus szükséges.
A Hive egy rést foglal el a SharedPreferences és az SQLite között. Bonyolultabb, mint a SharedPreferences (támogatja az egyedi objektumokat), de egyszerűbb, mint az SQLite (nem igényel SQL lekérdezéseket). Hasonlítsuk össze a legfontosabb jellemzőket.
| Jellemző | Hive | SharedPreferences | SQLite |
|---|---|---|---|
| Adattípusok | Bármilyen (TypeAdapter-en keresztül) | Csak primitívek | SQL típusok |
| Olvasási sebesség | ~30 000 ops/s | ~5 000 ops/s | ~2 000 ops/s |
| Natív kód | Nem szükséges | Szükséges (Android) | Szükséges |
| Web támogatás | Igen | Nem | Nem |
| Bonyolultság | Alacsony | Minimális | Közepes |
| Reaktivitás | WatchBox | Nem | ORM-en keresztül |
A Hive optimális kis adatmennyiségekhez: alkalmazásbeállítások, API válaszok gyorsítótára, helyi szinkronizációs sor, kedvencek és böngészési előzmények. Ha az adatok nem haladják meg az 50 MB-ot és nem igényelnek relációs lekérdezéseket — a Hive gyorsabb és egyszerűbb, mint az SQLite.
A Hive nem támogatja a több mezőre szűrést, JOIN-t, aggregált függvényeket tartalmazó lekérdezéseket. Ha összetett lekérdezésekre van szüksége, mint “az összes mai feladat kiválasztása 3 feletti prioritással” — használja az SQLite-ot drift-tel vagy floor-ral. A Hive szintén nem alkalmas 100 MB-nál több adat tárolására a memóriába töltés miatt.
A Hive az inicializálással és a Box megnyitásával kezdődik. Az alábbiakban az alapvető műveletek láthatók egy tipikus forgatókönyvhöz — feladatlista tárolása Flutter alkalmazásban. Minden példa natív platformhívások nélkül működik.
A Hive használata előtt meg kell hívni a Hive.initFlutter()-t a main függvényben. Ezután nyissa meg a Box-ot a Hive.openBox() segítségével — az eredmény egy olvasásra és írásra kész Box példány lesz.
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());
}
A Box put, get, delete metódusokat biztosít, és tartalmaz egy iterátort az összes rekord bejárásához. A kulcsok és értékek generikusokon keresztül tipizáltak — alapértelmezés szerint a Box<dynamic> bármilyen típust engedélyez, de ajánlott konkrét típust megadni.
// Adatok írása
final box = await Hive.openBox<String>('tasks');
await box.put('task_1', 'Termékek vásárlása');
// Olvasás
final task = box.get('task_1');
// Összes kulcs
final allTasks = box.values.toList();
// Törlés
await box.delete('task_1');
// Box törlése
await box.clear();
A WatchBox — a Box kiterjesztése, amely értesíti a feliratkozókat a változásokról. Flutter-ben ez a ValueListenableBuilder-rel integrálódik: amikor bármely érték megváltozik a Box-ban, a widget automatikusan újraépül a setState meghívása nélkül.
final watchBox = await Hive.openBox('settings');
// Widget-ben
ValueListenableBuilder(
valueListenable: watchBox.listenable(),
builder: (context, box, _) {
final counter = box.get('counter') ?? 0;
return Text('Számláló: $counter');
},
)
A TypeAdapter — a Hive mechanizmusa egyedi Dart objektumok szerializálására. Az adapter leírja, hogyan kell egy objektumot bináris formátumba (write) és vissza (read) alakítani. A json_serializable-sal ellentétben a TypeAdapter nem igényel reflexiót és gyorsabban működik.
Az adapter a TypeAdapter
// Adatmodell
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);
}
}
Sok modellel rendelkező projektekhez a Hive hive_generator-t és build_runner-t biztosít. A @HiveType annotáció az osztályon és a @HiveField a mezőkön automatikusan generálja az adaptert. Ez akkor kényelmes, ha a modell 10+ mezőt tartalmaz — a kézi read/write írás munkaigényessé válik.
A Hive az olvasást memóriából végzi, nem a lemezről, ami akár 30 000 műveletet is jelent másodpercenként. Optimalizáláshoz: nyissa meg a Box-ot egyszer, és használja újra az egész alkalmazásban, ne hívja meg újra az openBox-ot. Használja a Hive.box()-ot (szinkron getter) inicializálás után — visszaadja a már megnyitott Box-ot anélkül, hogy új példányt hozna létre.
A Hive könnyen integrálható a népszerű Flutter állapotkezelőkkel. Provider esetén használjon ChangeNotifierProvider-t, amely inicializáláskor beolvassa az adatokat a Box-ból, és listenable-en keresztül frissül. Riverpod esetén a WatchBox-ra feliratkozó StreamProvider megfelelő. Egy ilyen kombináció reaktív UI frissítéseket biztosít minden adatváltozáskor a Hive-ban kézi setState hívás nélkül. Egy tipikus Flutter projektben egy ilyen architektúra lehetővé teszi az állapot szinkronizálását a képernyők között globális singleton nélkül.
Gyakran ismételt kérdések
A Hive tiszta Dart-ban működik, így bármilyen Dart projektben használható: szerver (Dart VM), konzol vagy AngularDart. Flutter esetén külön csatlakozik a hive_flutter a tárolási útvonalak inicializálásával.
A Hive támogatja az AES-256 titkosítást az encryptionKey paraméteren keresztül a Box megnyitásakor. A kulcsnak 32 bájtos sztringnek kell lennie. A titkosított Box kulcs nélkül nem olvasható — az adatok fájlszinten védettek.
Az Isar — a Hive utódja ugyanattól a szerzőtől (Simon Leiter). Az Isar gyorsabb, támogatja az indexeket, kapcsolatokat és összetett lekérdezéseket. Azonban a Hive továbbra is releváns egyszerű forgatókönyvekhez, ahol nincs szükség az Isar relációs képességeire, és olyan projektekhez, ahol a minimális függőség fontos.
A Hive nem rendelkezik beépített migrációval. Ha a TypeAdapter szerkezete megváltozott, a régi adatok nem deszerializálódnak. Megoldás: növelje az adapter typeId-ját, és írjon kézi migrációt a kódban, vagy használja a delete-et a régi kulcshoz az új írása előtt.
A Hive a Box-ot teljesen a memóriába tölti. Az ajánlott határ 50-100 MB Box-onként. Túllépés esetén késések léphetnek fel a Box megnyitásakor és megnövekedett RAM fogyasztás. Nagyobb mennyiségekhez használjon több Box-ot vagy LazyBox-ot lusta betöltéssel.
Összegzés
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is