Налаштування бази даних ObjectBox в мобільному додатку
ObjectBox позиціонує себе як найшвидшу вбудовану базу даних для мобільних пристроїв. Бенчмарки компанії показують 10-разну перевагу перед Room/SQLite за операціями запису. На практиці розрив залежить від паттернів доступу, але ObjectBox дійсно швидший при масовій вставці об'єктів завдяки своєму нативному C++ рушію без SQL-парсингу.
Коли ObjectBox має сенс
ObjectBox — об'єктна база, не реляційна. Немає JOIN, немає GROUP BY, немає агрегатних функцій у традиційному SQL-сенсі. Якщо ваш додаток працює з графом об'єктів (сутності зі зв'язками), а не з аналітичними запитами, ObjectBox перемагає. Для IoT-додатків, трекерів, ігрових збережень, каталогів з фільтруванням — добре підходить.
Підключення та моделі
// build.gradle (app)
plugins {
id("io.objectbox")
}
dependencies {
implementation("io.objectbox:objectbox-kotlin:3.8.0")
}
@Entity
data class Task(
@Id var id: Long = 0,
var title: String = "",
var description: String = "",
var priority: Int = 0,
var dueDate: Long = 0,
var isCompleted: Boolean = false
) {
// Зв'язки ToMany налаштовуються через RelationInfo
val tags: ToMany<Tag> = toMany()
}
@Entity
data class Tag(
@Id var id: Long = 0,
var name: String = "",
@Index var color: String = ""
)
@Id — обов'язковий Long для внутрішнього ObjectBox ID. Це не UUID і не ваш бізнес-ідентифікатор — використовуйте окреме текстове поле для синхронізації з сервером.
Ініціалізація та BoxStore
// Клас Application
class MyApp : Application() {
companion object {
lateinit var boxStore: BoxStore
private set
}
override fun onCreate() {
super.onCreate()
boxStore = MyObjectBox.builder()
.androidContext(this)
.name("tasks-db")
.build()
}
}
// Використання у ViewModel
class TaskViewModel : ViewModel() {
private val taskBox: Box<Task> = MyApp.boxStore.boxFor(Task::class.java)
val tasks: LiveData<List<Task>> = liveData(Dispatchers.IO) {
val query = taskBox.query(Task_.isCompleted.equal(false))
.order(Task_.priority, QueryBuilder.DESCENDING)
.build()
emitSource(query.subscribe().toLiveData())
}
}
query.subscribe().toLiveData() — ObjectBox DataObserver автоматично сповіщає при змінах даних у боксі. Це реактивна підписка без лишнього коду.
Запити через QueryBuilder
ObjectBox не використовує SQL-рядки. Запити через типобезпечний QueryBuilder з Properties — згенерованими метаклассами (Task_, Tag_):
// Фільтрація з кількома умовами
val urgentTasks = taskBox.query(
Task_.isCompleted.equal(false)
.and(Task_.priority.greater(2))
.and(Task_.dueDate.less(System.currentTimeMillis() + 86_400_000L))
)
.order(Task_.dueDate)
.build()
.find()
// Повнотекстовий пошук вимагає @Index(type = IndexType.VALUE) + FTS
val searchResults = taskBox.query(
Task_.title.contains("meeting", StringOrder.CASE_INSENSITIVE)
)
.build()
.find()
Без JOIN — зв'язки через ToOne/ToMany. ObjectBox ледачо завантажує пов'язані об'єкти за замовчуванням:
// ToMany завантажується при першому звертанні
val taskTags = task.tags // ледача загрузка, доступ до БД
ObjectBox Sync
Як і Realm, ObjectBox пропонує комерційний сервер синхронізації — ObjectBox Sync. Двостороння синхронізація, розв'язання конфліктів, дельта-оновлення. Це окремий продукт з ліцензійною моделлю.
Типові проблеми
ID не UUID. ObjectBox присвоює Long ID автоматично — вони унікальні лише локально. Для серверної синхронізації потрібне окреме UUID-поле з @Index.
Кодген при кожній збірці. Плагін генерує MyObjectBox.java та _ класи. Якщо схема змінилася, а gradle кеш не скинувся — компілятор скаржиться на невідповідність. ./gradlew clean вирішує.
Відкритий BoxStore — один на додаток. Спроба відкрити другий BoxStore на той самий файл — виняток. Singleton через клас Application обов'язковий.
Налаштування ObjectBox, моделі, реактивні запити для Android: 3–5 днів. Вартість розраховується індивідуально.







