Hive — lichte NoSQL-opslag voor Flutter die zonder native code werkt. In tegenstelling tot SQLite of Firebase heeft Hive geen native bibliotheken nodig en werkt het uitsluitend via Dart. Volgens Pub.dev, 2024 is Hive meer dan 10 miljoen keer gedownload en wordt het gebruikt in elke derde Flutter-project dat lokale gegevensopslag vereist zonder serverinfrastructuur.
Belangrijkste punten
Hive — is een NoSQL-database die volledig in Dart is geschreven en geen native bibliotheken nodig heeft. Het is gemaakt door Simon Leiter in 2019 als alternatief voor SQLite voor Flutter-projecten. Hive slaat gegevens op in binair formaat .hive, geoptimaliseerd voor snel lezen en schrijven op mobiele apparaten. Het .hive-formaat gebruikt een aangepast serialisatieschema waarbij elk gegevenstype zijn eigen byteprefix heeft, waardoor het bestand kan worden gelezen zonder voorkennis van het schema — in tegenstelling tot Protocol Buffers of FlatBuffers.
Het hoofdidee van Hive — maximale eenvoud. De database vereist geen initialisatie van native engines, bevat geen SQL-parser en gebruikt geen reflectie. Alle bewerkingen zijn directe aanroepen van Dart-functies met binaire serialisatie via WriteBuffer en ReadBuffer.
Volgens een enquête van Flutter Community (2023) staat Hive in de top 5 van meest gebruikte pakketten voor gegevensopslag in Flutter, alleen tweede na shared_preferences in populariteit, maar overtreft het in functionaliteit en snelheid.
Hive gebruikt het concept van Box — analoog aan een tabel in relationele databases. Elke Box is een bestand op schijf met een set sleutel-waardeparen. De sleutel kan int of String zijn, de waarde — elk primitief type, lijst, Map of een aangepast object via TypeAdapter. Boxen zijn van elkaar geïsoleerd en worden onafhankelijk geopend.
Hive heeft geen platformkanalen (platform channels) nodig. Dit betekent dat het hetzelfde werkt op Android, iOS, Web, macOS, Windows en Linux zonder extra configuratie. Voor projecten gericht op webcompilatie blijft Hive de enige lichte NoSQL-oplossing — SQLite werkt niet in de browser. Tegelijkertijd gebruikt Hive IndexedDB als backend voor het web, wat gegevenspersistentie in de browseromgeving garandeert.
Hive serialiseert gegevens naar binair formaat bij schrijven en deserialiseert bij lezen. Het interne mechanisme is gebaseerd op BinaryWriter en BinaryReader, die gegevens in compacte byte-arrays verpakken. De opslaggrootte op schijf is gemiddeld 2-3 keer kleiner dan de JSON-representatie van dezelfde gegevens.
Bij het openen van een Box laadt Hive het hele bestand in het RAM-geheugen. Dit zorgt voor hoge leessnelheid (microseconden), maar legt een beperking op aan de gegevensgrootte: het wordt aanbevolen om niet meer dan 50-100 MB per Box op te slaan. Voor grotere volumes gebruikt u LazyBox — lui laden van records van schijf.
Hive werkt single-threaded in de isolatie van Dart-isolate. Schrijfbewerkingen worden synchroon uitgevoerd met bestandsvergrendeling. Voor asynchrone toegang gebruikt u Hive.openBox() met await. Gelijktijdige toegang vanuit meerdere isolates wordt niet direct ondersteund — hiervoor is een apart synchronisatiemechanisme nodig.
Hive bevindt zich in een niche tussen SharedPreferences en SQLite. Het is complexer dan SharedPreferences (ondersteunt aangepaste objecten), maar eenvoudiger dan SQLite (geen SQL-query's nodig). Laten we de belangrijkste kenmerken vergelijken.
| Kenmerk | Hive | SharedPreferences | SQLite |
|---|---|---|---|
| Gegevenstypen | Elk (via TypeAdapter) | Alleen primitieven | SQL-typen |
| Leessnelheid | ~30 000 ops/s | ~5 000 ops/s | ~2 000 ops/s |
| Native code | Niet nodig | Vereist (Android) | Vereist |
| Webondersteuning | Ja | Nee | Nee |
| Complexiteit | Laag | Minimaal | Gemiddeld |
| Reactiviteit | WatchBox | Nee | Via ORM |
Hive is optimaal voor kleine hoeveelheden gegevens: app-instellingen, cache van API-antwoorden, lokale synchronisatiewachtrij, favorieten en browsegeschiedenis. Als gegevens niet groter zijn dan 50 MB en geen relationele query's vereisen — is Hive sneller en eenvoudiger dan SQLite.
Hive ondersteunt geen query's met filtering op meerdere velden, JOIN, aggregatiefuncties. Als u complexe query's nodig hebt zoals “selecteer alle taken voor vandaag met prioriteit hoger dan 3” — gebruik dan SQLite met drift of floor. Hive is ook niet geschikt voor het opslaan van meer dan 100 MB aan gegevens vanwege het laden in het geheugen.
Hive begint met initialisatie en het openen van een Box. Hieronder staan de basisbewerkingen voor een typisch scenario — het opslaan van een takenlijst in een Flutter-app. Alle voorbeelden werken zonder native platformaanroepen.
Voordat u Hive gebruikt, moet Hive.initFlutter() worden aangeroepen in de main-functie. Open vervolgens de Box via Hive.openBox() — het resultaat is een Box-instantie die klaar is voor lezen en schrijven.
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 biedt methoden put, get, delete en bevat een iterator om alle records te doorlopen. Sleutels en waarden worden getypeerd via generieken — standaard staat Box<dynamic> alle typen toe, maar het wordt aanbevolen een specifiek type op te geven.
// Gegevens schrijven
final box = await Hive.openBox<String>('tasks');
await box.put('task_1', 'Producten kopen');
// Lezen
final task = box.get('task_1');
// Alle sleutels
final allTasks = box.values.toList();
// Verwijderen
await box.delete('task_1');
// Box opschonen
await box.clear();
WatchBox — een uitbreiding van Box die abonnees op de hoogte stelt van wijzigingen. In Flutter integreert dit met ValueListenableBuilder: bij wijziging van een waarde in de Box wordt de widget automatisch herbouwd zonder setState aan te roepen.
final watchBox = await Hive.openBox('settings');
// In widget
ValueListenableBuilder(
valueListenable: watchBox.listenable(),
builder: (context, box, _) {
final counter = box.get('counter') ?? 0;
return Text('Teller: $counter');
},
)
TypeAdapter — Hive's mechanisme voor serialisatie van aangepaste Dart-objecten. De adapter beschrijft hoe een object naar binair formaat (write) en terug (read) wordt omgezet. In tegenstelling tot json_serializable heeft TypeAdapter geen reflectie nodig en werkt het sneller.
De adapter implementeert de interface TypeAdapter
// Gegevensmodel
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);
}
}
Voor projecten met veel modellen biedt Hive hive_generator en build_runner. De annotatie @HiveType op de klasse en @HiveField op velden genereert de adapter automatisch. Dit is handig wanneer het model 10+ velden bevat — handmatig read/write schrijven wordt tijdrovend.
Hive voert lezingen uit vanuit het geheugen, niet van schijf, wat snelheid tot 30 000 bewerkingen per seconde oplevert. Voor optimalisatie: open de Box eenmalig en hergebruik deze in de hele app, roep openBox niet opnieuw aan. Gebruik Hive.box() (synchrone getter) na initialisatie — retourneert een reeds geopende Box zonder een nieuwe instantie te maken.
Hive integreert eenvoudig met populaire Flutter state-managers. Gebruik voor Provider een ChangeNotifierProvider die gegevens uit de Box leest bij initialisatie en wordt bijgewerkt via listenable. Voor Riverpod is een StreamProvider die is geabonneerd op WatchBox geschikt. Zo'n combinatie biedt reactieve UI-updates bij elke gegevenswijziging in Hive zonder handmatige setState-aanroep. In een typisch Flutter-project maakt dergelijke architectuur synchronisatie van de toestand tussen schermen mogelijk zonder globale singleton.
Veelgestelde vragen
Hive werkt in pure Dart, dus het kan worden gebruikt in elk Dart-project: server (Dart VM), console of AngularDart. Voor Flutter wordt aanvullend hive_flutter met initialisatie van opslagpaden aangesloten.
Hive ondersteunt AES-256-versleuteling via de parameter encryptionKey bij het openen van een Box. De sleutel moet een 32-byte string zijn. Een versleutelde Box kan niet worden gelezen zonder de sleutel — gegevens zijn beschermd op bestandsniveau.
Isar — de opvolger van Hive van dezelfde auteur (Simon Leiter). Isar is sneller, ondersteunt indexen, relaties en complexe query's. Hive blijft echter relevant voor eenvoudige scenario's waar de relationele mogelijkheden van Isar niet nodig zijn en voor projecten waar minimale afhankelijkheid belangrijk is.
Hive heeft geen ingebouwde migraties. Als de TypeAdapter-structuur is gewijzigd, worden oude gegevens niet gedeserialiseerd. Oplossing: verhoog de typeId van de adapter en schrijf een handmatige migratie in code, of gebruik delete voor de oude sleutel voordat u een nieuwe schrijft.
Hive laadt de Box volledig in het geheugen. De aanbevolen limiet is 50-100 MB per Box. Bij overschrijding zijn vertragingen bij het openen van de Box en verhoogd RAM-verbruik mogelijk. Voor grotere volumes gebruikt u meerdere Boxen of LazyBox met lui laden.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook