ObjectBox é um banco de dados NoSQL de alto desempenho otimizado para dispositivos móveis e edge. Ao contrário do SQLite, ele usa seu próprio formato de armazenamento de arquivos planos sem camada SQL. De acordo com ObjectBox Benchmarks, 2024, o ObjectBox executa operações de inserção e leitura de 10 a 100 vezes mais rápido que o SQLite em dispositivos Android, tornando-o a melhor escolha para aplicativos móveis de alta carga.
Principais pontos
ObjectBox é um banco de dados NoSQL in-memory desenvolvido pela empresa alemã ObjectBox.io. Ao contrário dos bancos de dados relacionais tradicionais, o ObjectBox armazena objetos diretamente em arquivos planos usando seu próprio formato SLOT (Super Lightweight Object Tree). Isso elimina a sobrecarga de ORM e análise SQL. O formato SLOT é otimizado para dispositivos com memória limitada: os dados são desfragmentados automaticamente e o tamanho do BD é em média 4 a 6 vezes menor que um banco de dados SQLite equivalente com o mesmo número de registros.
O ObjectBox suporta todas as principais plataformas móveis: Android, iOS e Flutter. Para Android, a geração de código está disponível através do ObjectBox Gradle Plugin, que processa entidades anotadas e cria classes Box para trabalhar com dados. Para Flutter, é usado um plugin nativo com wrapper Dart. Além das plataformas móveis, o ObjectBox funciona em Linux, macOS, Windows e WebAssembly, permitindo reutilizar o modelo de dados entre o aplicativo móvel e a sincronização do servidor.
De acordo com um estudo da ObjectBox (2023), o banco de dados é usado em mais de 5.000 aplicativos no Google Play, incluindo aplicativos com mais de 10 milhões de usuários. Principais casos de uso: cache de dados, operação offline e armazenamento de séries temporais (IoT). O ObjectBox é especialmente popular em aplicativos de monitoramento de saúde e fitness que exigem registro rápido de leituras de sensores no dispositivo sem conexão constante com a internet e para coletar análises de vários dispositivos.
ObjectBox surgiu como uma alternativa ao Realm e SQLite para a plataforma Android. A primeira versão estável foi lançada em 2018. A principal diferença do Realm é que o ObjectBox não tem restrições GPL (usa Apache 2.0) e suporta mais plataformas: de dispositivos móveis a servidores Linux.
ObjectBox fornece: geração automática de classes Box, índices integrados para pesquisa rápida, transações com suporte a rollback, consultas reativas via RxJava e Kotlin Flow e sincronização entre dispositivos através do ObjectBox Sync (protocolo proprietário). Ao contrário do Firebase Realtime Database, o ObjectBox Sync funciona em um modelo peer-to-peer sem servidor central, reduzindo a latência e os custos de infraestrutura.
ObjectBox armazena dados em seu próprio formato binário .mdb (ObjectBox Data File). Cada entidade é mapeada para um arquivo, onde os registros são armazenados sequencialmente com um deslocamento fixo. Isso permite ler e escrever objetos individuais sem verificação completa do arquivo.
Trabalhar com ObjectBox não requer SQL: as consultas são construídas através de uma API fluente no código. O compilador gera classes auxiliares MyObjectBox e Boxes que encapsulam todas as operações CRUD. O modelo de dados é descrito usando anotações @Entity, @Id, @Index e @Relation.
// Connecting ObjectBox in Android
class App: Application() {
lateinit var boxStore: BoxStore
override fun onCreate() {
super.onCreate()
boxStore = MyObjectBox.builder()
.androidContext(this)
.build()
}
}
De acordo com benchmarks oficiais, o ObjectBox supera significativamente o SQLite em velocidade, especialmente em inserções em lote e leituras em massa. No entanto, o SQLite continua sendo o padrão de facto para aplicativos móveis devido à sua prevalência e suporte SQL integrado.
| Operação | ObjectBox | SQLite | Diferença |
|---|---|---|---|
| Inserção (1000 registros) | ~5 ms | ~180 ms | x36 mais rápido |
| Leitura (1000 registros) | ~3 ms | ~70 ms | x23 mais rápido |
| Atualização (1000 registros) | ~6 ms | ~150 ms | x25 mais rápido |
| Pesquisa por índice | ~0.1 ms | ~2 ms | x20 mais rápido |
| Tamanho do BD (1000 objetos) | ~28 KB | ~112 KB | 4 vezes menor |
ObjectBox fica aquém do SQLite em cenários que exigem consultas JOIN complexas, funções agregadas (SUM, COUNT com agrupamento) ou integração com um esquema SQL existente. Se o projeto já usa SQLite com Room ORM, migrar para ObjectBox exigirá reescrever toda a lógica de acesso a dados. O ObjectBox também não oferece suporte a consultas SQL personalizadas — apenas API fluente. No entanto, para operações CRUD típicas e cache, o ObjectBox fornece uma melhoria de desempenho de até 100 vezes, conforme confirmado por benchmarks oficiais em dispositivos Android com diferentes versões do sistema operacional.
ObjectBox usa anotações para definir entidades. Após a compilação, classes Box são criadas com métodos put, get, remove e query. Abaixo estão operações típicas para um modelo Task em um aplicativo de lista de tarefas.
Cada entidade é anotada com @Entity. Um campo com @Id se torna a chave primária, e @Index acelera as pesquisas nesse campo. O ObjectBox suporta geração automática de ID quando o valor é 0.
@Entity
data class Task(
@Id var id: Long = 0,
@Index var title: String = "",
var isCompleted: Boolean = false,
var priority: Int = 0
)
Box é a classe principal para trabalhar com entidades. O método put() salva ou atualiza um objeto, get() lê por ID e remove() exclui. Todas as operações básicas são síncronas e executadas na thread de chamada.
val taskBox: Box<Task> = boxStore.boxFor(Task::class.java)
// Create
val task = Task(title = "Buy products", priority = 3)
val newId = taskBox.put(task)
// Read
val savedTask = taskBox.get(newId)
// Update
savedTask.isCompleted = true
taskBox.put(savedTask)
// Delete
taskBox.remove(newId)
ObjectBox suporta consultas reativas via .subscribe(). O assinante recebe notificações quando os dados que correspondem à condição da consulta mudam. Isso é conveniente para a interface do usuário que atualiza automaticamente a lista quando itens são adicionados ou removidos.
val query = taskBox.query()
.equal(Task_.isCompleted, false)
.orderDesc(Task_.priority)
.build()
query.subscribe { tasks ->
// tasks — List, atualiza automaticamente
updateUi(tasks)
}
ObjectBox suporta relacionamentos entre entidades — Um-para-Um, Um-para-Muitos e Muitos-para-Muitos. Os relacionamentos são definidos através da anotação @Relation. Ao contrário do SQLite, o ObjectBox não usa chaves estrangeiras: os relacionamentos são implementados através de listas de IDs em arquivos planos, o que acelera a navegação no grafo de objetos.
O relacionamento @Backlink permite navegar de uma entidade filha para sua entidade pai sem um campo de referência separado. O ObjectBox mantém automaticamente o backlink, eliminando a duplicação de dados e a sincronização entre duas tabelas.
ObjectBox Query Builder permite construir cadeias de condições: equal, notEqual, greater, less, in, contains, startsWith. Todas as condições podem ser combinadas através de and/or. O resultado pode ser classificado, limitado e obtido como List ou LazyList (para grandes conjuntos de dados).
ObjectBox indexa automaticamente o campo @Id. Para índices personalizados, use a anotação @Index em campos que são consultados com frequência. Os índices aceleram consultas equal e in, mas retardam inserções — não indexe campos que não são pesquisados. O ObjectBox suporta índices compostos para filtrar por vários campos simultaneamente. Índices compostos são especialmente úteis para filtros de lista: por exemplo, pesquisar tarefas incompletas com prioridade alta é dezenas de vezes mais rápido com um índice composto nos campos isCompleted e priority.
ObjectBox Sync é uma tecnologia proprietária para sincronização de dados em tempo real entre dispositivos. Ele usa um protocolo baseado em WebSocket com resolução de conflitos por last-writer-wins. O Sync é adequado para aplicativos que precisam de sincronização offline: notas, listas de tarefas, dados IoT de vários sensores. No entanto, é necessária a compra de uma licença para produção.
// Query with multiple conditions
val highPriorityIncomplete = taskBox.query()
.greater(Task_.priority, 5)
.equal(Task_.isCompleted, false)
.build()
.find()
// Substring search
val searchResults = taskBox.query()
.contains(Task_.title, "product", StringOrder.CASE_INSENSITIVE)
.build()
.find()
Perguntas frequentes
ObjectBox é distribuído sob a licença Apache 2.0, que permite uso comercial sem restrições. O recurso ObjectBox Sync (sincronização multiplataforma) é proprietário e requer a compra de uma licença para produção.
BoxStore é thread-safe: várias threads podem ler dados simultaneamente. As gravações são bloqueadas no nível do Box. Para transações complexas, use boxStore.runInTx(), que garante a atomicidade de um grupo de operações.
Sim, o ObjectBox suporta Kotlin Multiplatform (KMP) a partir da versão 3.0. Os targets disponíveis são Android, iOS, JVM e Native. Para KMP, é usado um plugin Gradle separado objectbox-kotlin com suporte expect/actual.
ObjectBox armazena dados em arquivos .mdb no diretório do aplicativo. Para backup, copie todo o diretório ObjectBox via BoxStore.copy() ou copie manualmente os arquivos após chamar boxStore.close(). Arquivos ativos não podem ser copiados — isso corromperá os dados.
Room é um ORM sobre SQLite, requer consultas SQL e tem sobrecarga de mapeamento de objetos. ObjectBox é um banco de dados NoSQL sem SQL, uma ordem de magnitude mais rápido, mas não suporta JOINs complexos e não é um banco de dados relacional. A escolha depende da tarefa: para dados relacionais — Room, para armazenamento rápido de objetos — ObjectBox.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também