ObjectBox este o bază de date NoSQL de înaltă performanță, optimizată pentru dispozitive mobile și edge. Spre deosebire de SQLite, utilizează propriul format de stocare bazat pe fișiere plate fără un strat SQL. Conform ObjectBox Benchmarks, 2024, ObjectBox execută operațiile de inserare și citire de 10–100 de ori mai rapid decât SQLite pe dispozitive Android, ceea ce îl face cea mai bună alegere pentru aplicațiile mobile cu încărcare mare.
Principalele puncte
ObjectBox este o bază de date NoSQL in-memory dezvoltată de compania germană ObjectBox.io. Spre deosebire de bazele de date relaționale tradiționale, ObjectBox stochează obiectele direct în fișiere plate, folosind propriul format SLOT (Super Lightweight Object Tree). Aceasta elimină suprasarcina ORM și a analizorului SQL. Formatul SLOT este optimizat pentru funcționarea pe dispozitive cu memorie limitată: datele sunt defragmentate automat, iar dimensiunea bazei de date este în medie de 4–6 ori mai mică decât o bază SQLite echivalentă cu același număr de înregistrări.
ObjectBox suportă toate platformele mobile principale: Android, iOS și Flutter. Pentru Android este disponibilă generarea de cod prin ObjectBox Gradle Plugin, care procesează entitățile adnotate și creează clase Box pentru lucrul cu datele. Pentru Flutter se utilizează un plugin nativ cu wrapper Dart. Pe lângă platformele mobile, ObjectBox funcționează pe Linux, macOS, Windows și WebAssembly, permițând reutilizarea modelului de date între aplicația mobilă și sincronizarea server.
Conform datelor cercetării ObjectBox (2023), baza de date este utilizată în peste 5000 de aplicații în Google Play, inclusiv aplicații cu o audiență de peste 10 milioane de utilizatori. Scenariile principale: stocarea în cache a datelor, lucrul în modul offline și stocarea seriilor temporale (IoT). ObjectBox este deosebit de popular în aplicațiile de urmărire a sănătății și fitness, unde este necesară înregistrarea rapidă a citirilor senzorilor pe dispozitiv fără conexiune permanentă la internet și colectarea de analize de pe mai multe dispozitive.
ObjectBox a apărut ca o alternativă la Realm și SQLite pentru platforma Android. Prima versiune stabilă a fost lansată în 2018. Diferența cheie față de Realm — ObjectBox nu are restricții GPL (folosește Apache 2.0) și suportă mai multe platforme: de la dispozitive mobile la servere Linux.
ObjectBox oferă: generare automată a claselor Box, indexuri încorporate pentru căutare rapidă, tranzacții cu suport pentru revenire, interogări reactive prin RxJava și Kotlin Flow, precum și sincronizare între dispozitive prin ObjectBox Sync (protocol proprietar). Spre deosebire de Firebase Realtime Database, ObjectBox Sync funcționează în model peer-to-peer fără un server central, ceea ce reduce latența și costurile de infrastructură.
ObjectBox stochează datele în propriul format binar .mdb (ObjectBox Data File). Fiecare entitate (Entity) este mapată la un fișier, unde înregistrările sunt stocate secvențial cu un offset fix. Acest lucru permite citirea și scrierea obiectelor individuale fără scanarea completă a fișierului.
Pentru a lucra cu ObjectBox nu este nevoie de SQL: interogările se construiesc prin API-ul fluent în cod. Compilatorul generează clasele ajutătoare MyObjectBox și cutiile (Box) care încapsulează toate operațiile CRUD. Modelul de date este descris prin adnotări @Entity, @Id, @Index și @Relation.
// Conectarea ObjectBox în Android
class App: Application() {
lateinit var boxStore: BoxStore
override fun onCreate() {
super.onCreate()
boxStore = MyObjectBox.builder()
.androidContext(this)
.build()
}
}
Conform evaluărilor oficiale, ObjectBox depășește semnificativ SQLite în ceea ce privește viteza operațiilor, în special la inserarea în lot și citirea în masă. Cu toate acestea, SQLite rămâne standardul de facto pentru aplicațiile mobile datorită răspândirii și suportului încorporat SQL.
| Operație | ObjectBox | SQLite | Diferență |
|---|---|---|---|
| Inserare (1000 înregistrări) | ~5 ms | ~180 ms | x36 mai rapid |
| Citire (1000 înregistrări) | ~3 ms | ~70 ms | x23 mai rapid |
| Actualizare (1000 înregistrări) | ~6 ms | ~150 ms | x25 mai rapid |
| Căutare după index | ~0.1 ms | ~2 ms | x20 mai rapid |
| Dimensiune BD (1000 obiecte) | ~28 KB | ~112 KB | de 4 ori mai mică |
ObjectBox pierde în fața SQLite în scenariile care necesită interogări complexe JOIN, funcții agregate (SUM, COUNT cu grupare) sau integrare cu o schemă SQL existentă. Dacă proiectul folosește deja SQLite cu Room ORM — migrarea la ObjectBox va necesita rescrierea întregii logici de acces la date. ObjectBox nu suportă nici interogări SQL personalizate — doar API fluent. Cu toate acestea, pentru operațiile tipice CRUD și stocarea în cache, ObjectBox oferă o creștere a performanței de până la 100 de ori, ceea ce este confirmat de evaluările oficiale pe dispozitive Android cu diferite versiuni de OS.
ObjectBox utilizează adnotări pentru definirea entităților. După compilare, se creează clase Box cu metodele put, get, remove și query. Mai jos sunt prezentate operațiile tipice pentru modelul Task într-o aplicație de listă de sarcini.
Fiecare entitate este adnotată cu @Entity. Câmpul cu @Id devine cheia primară, @Index accelerează căutarea după câmp. ObjectBox suportă generarea automată a ID-ului la valoarea 0.
@Entity
data class Task(
@Id var id: Long = 0,
@Index var title: String = "",
var isCompleted: Boolean = false,
var priority: Int = 0
)
Box — clasa principală pentru lucrul cu entitățile. Metoda put() salvează sau actualizează obiectul, get() citește după ID, remove() șterge. Toate operațiile de bază sunt sincrone și se execută pe thread-ul apelant.
val taskBox: Box<Task> = boxStore.boxFor(Task::class.java)
// Creare
val task = Task(title = "Cumpără produse", priority = 3)
val newId = taskBox.put(task)
// Citire
val savedTask = taskBox.get(newId)
// Actualizare
savedTask.isCompleted = true
taskBox.put(savedTask)
// Ștergere
taskBox.remove(newId)
ObjectBox suportă interogări reactive prin .subscribe(). Abonatul primește notificări la orice modificare a datelor care corespund condiției interogării. Acest lucru este convenabil pentru UI care actualizează automat lista la adăugarea sau ștergerea elementelor.
val query = taskBox.query()
.equal(Task_.isCompleted, false)
.orderDesc(Task_.priority)
.build()
query.subscribe { tasks ->
// tasks — List, se actualizează automat
updateUi(tasks)
}
ObjectBox suportă relații între entități — To-One, To-Many și Many-to-Many. Relațiile se definesc prin adnotarea @Relation. Spre deosebire de SQLite, ObjectBox nu utilizează chei externe: relațiile sunt implementate prin liste de ID-uri în fișiere plate, ceea ce accelerează navigarea prin graful de obiecte.
Relația @Backlink permite trecerea de la entitatea copil la părinte fără un câmp de referință separat. ObjectBox menține automat referința inversă, eliminând duplicarea datelor și sincronizarea între două tabele.
ObjectBox Query Builder permite construirea unor lanțuri de condiții: equal, notEqual, greater, less, in, contains, startsWith. Toate condițiile se combină prin and/or. Rezultatul poate fi sortat, limitat și obținut ca List sau LazyList (pentru seturi mari de date).
ObjectBox indexează automat câmpul @Id. Pentru indexuri personalizate, utilizați adnotarea @Index pe câmpurile după care se execută frecvent interogări. Indexurile accelerează interogările equal și in, dar încetinesc inserarea — nu indexați câmpurile după care nu se face căutare. ObjectBox suportă indexuri compuse pentru filtrarea simultană după mai multe câmpuri. Indexurile compuse sunt deosebit de utile pentru filtrele din liste: de exemplu, căutarea sarcinilor nefinalizate cu prioritate ridicată este de zeci de ori mai rapidă cu un index compus pe câmpurile isCompleted și priority.
ObjectBox Sync — tehnologie proprietară pentru sincronizarea datelor între dispozitive în timp real. Utilizează un protocol bazat pe WebSocket cu rezolvare a conflictelor după principiul last-writer-wins. Sync este potrivit pentru aplicațiile care necesită sincronizare offline: note, liste de sarcini, date IoT de la mai mulți senzori. Cu toate acestea, pentru producție este necesară achiziționarea unei licențe.
// Interogare cu mai multe condiții
val highPriorityIncomplete = taskBox.query()
.greater(Task_.priority, 5)
.equal(Task_.isCompleted, false)
.build()
.find()
// Căutare după subșir
val searchResults = taskBox.query()
.contains(Task_.title, "produs", StringOrder.CASE_INSENSITIVE)
.build()
.find()
Întrebări frecvente
ObjectBox este distribuit sub licența Apache 2.0, care permite utilizarea comercială fără restricții. Funcția ObjectBox Sync (sincronizare multiplatformă) este proprietară și necesită achiziționarea unei licențe pentru producție.
BoxStore este thread-safe: mai multe thread-uri pot citi date simultan. Scrierea este blocată la nivel de Box. Pentru tranzacții complexe utilizați boxStore.runInTx(), care garantează atomicitatea unui grup de operații.
Da, ObjectBox suportă Kotlin Multiplatform (KMP) începând cu versiunea 3.0. Sunt disponibile target-urile Android, iOS, JVM și Native. Pentru KMP se utilizează un plugin Gradle separat objectbox-kotlin cu suport expect/actual.
ObjectBox stochează datele în fișiere .mdb în directorul aplicației. Pentru backup, copiați întregul director ObjectBox prin BoxStore.copy() sau manual după apelarea boxStore.close(). Fișierele live nu pot fi copiate — acest lucru va deteriora datele.
Room — ORM peste SQLite, necesită interogări SQL și are suprasarcină pentru maparea obiectelor. ObjectBox este NoSQL fără SQL, mult mai rapid, dar nu suportă JOIN-uri complexe și nu este o bază de date relațională. Alegerea depinde de sarcină: pentru date relaționale — Room, pentru stocare rapidă de obiecte — ObjectBox.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și