美文网首页Android开发
ObjectBox 最详细的使用指南

ObjectBox 最详细的使用指南

作者: 因为我的心 | 来源:发表于2023-04-26 14:16 被阅读0次

一、前言:

ObjectBox 官网:
git地址点击:

以前开发项目的时候 ORM 一直用的是 GreenDao ,这次新开项目的时候访问 GreenDao 的官网的时候却发现了一行新的 Note: for new apps we recommend ObjectBox, a new object-oriented database that is much faster than SQLite and easier to use. For existing apps based on greenDAO we offer DaoCompat for an easy switch (see also the announcement).

翻译:注意:对于新的应用程序,我们推荐ObjectBox,这是一种新的面向对象数据库,它比SQLite快得多,也更容易使用。对于基于greenDAO的现有应用程序,我们提供了DaoCompat,以便轻松切换(另请参阅公告)。

瞅一眼官网简介:ObjectBox is a super fast mobile database that persists objects. It lets you avoid many repetitive tasks and offers a simple interface to your data. 翻译一下就是:更快,更简单。翻了一下 FAQ,对比了一下 ObjectBox 和 谷歌两位亲儿子 Realm 和 Room ,如下图:

图片.png

从图上可以看出除了在加载 100k 的大量数据的时候 ObjectBox 的速度慢于 Realm,在执行其他数据操作的时候 ObjectBox 的性能对其他两位都是近乎碾压式的存在。

在引入后对 apk 包的大小影响方面,ObjectBox 和 Realm 分别在 1-1.5MB 和 3-4MB ,Room 因为是对 SQLite 的封装,只有 50KB 左右。而在增加的方法数量方面,Room 的 300 个方法也远少于 Room 的 2000 个方法和 ObjectBox 的 1300 个方法。关于三者的对比,可以看这篇文章:https://notes.devlabs.bg/realm-objectbox-or-room-which-one-is-for-you-3a552234fd6e

注意:如果不考虑对包的体积大小的影响,只考虑性能的话,似乎就有了选择 ObjectBox 的理由。

1、ObjectBox的特点

  • 高性能:ObjectBox 是一个高性能的 NoSQL 数据库,能够快速地存储和检索数据。
  • 易于使用:ObjectBox 提供了简单易用的 API,使得开发人员可以轻松地将其集成到应用程序中。
  • 跨平台:ObjectBox 支持多种平台,包括 Android、iOS、Linux、Windows 和 macOS。
  • 数据模型灵活:ObjectBox 具有灵活的数据模型,可以轻松地适应不同的数据结构和需求。
  • 数据同步:ObjectBox 支持数据同步,可以在多个设备之间同步数据。
  • 数据安全:ObjectBox 提供了数据加密和身份验证等安全功能,保护数据的安全性。
  • 高可靠性:ObjectBox 具有高可靠性,能够保证数据的完整性和可靠性。

2、greenDao、room和objectBox对比

greenDao、room和objectBox都是Android平台上的ORM(对象关系映射)框架,用于简化应用程序与数据库之间的交互。它们都有各自的优点和适用场景。

  • greenDao是一个轻量级的ORM框架,它的主要特点是速度快、内存占用小、易于使用。它使用代码生成器来生成DAO(数据访问对象)类,这些类可以直接访问数据库,从而避免了手动编写SQL语句的繁琐过程。greenDao支持多线程操作和事务处理,可以在高并发的情况下保证数据的一致性。它还提供了一些高级功能,如缓存、查询优化等。
  • room是Google官方推出的ORM框架,它是基于SQLite数据库的,可以与SQLite API无缝集成。room使用注解来定义实体类和DAO接口,可以自动生成数据库表和DAO实现类。它支持类型安全的查询、事务处理、观察者模式等功能。room还提供了LiveData和ViewModel等组件,可以方便地实现数据的观察和管理。
  • objectBox是一个高性能的ORM框架,它使用了一些新的技术来提高数据访问的效率。objectBox使用基于内存的数据结构来存储数据,可以快速地进行查询和更新操作。它还支持多线程操作和事务处理,可以在高并发的情况下保证数据的一致性。objectBox还提供了一些高级功能,如索引、关系映射、查询优化等。

总的来说,greenDao适合对性能要求较高的应用程序,room适合与Android架构组件一起使用的应用程序,objectBox适合需要高性能和高可扩展性的应用程序。选择哪个ORM框架取决于具体的应用场景和需求。

二、ObjectBox 常见的问题:

1、找不到MyObjectBox类

答:初次引入ObjectBox的时候,在使用MyObjectBox类之前,需要先完成一次编译,然后再创建数据bean对象,最后ObjectBox生成MyObjectBox类以后才能使用。

2、ObjectBox编译无法产生MyObjectBox类

1、目前(objectbox 2.2.0)还不支持在数据库bean里面添加集合属性,比如,List<String>,List<Object>等。针对此类情况,可以

1.1.对于集合元素为基础数据类型的属性,例如List<String>,可以转换为一个Json字符串存储,将集合属性转变为String类型;
1.2.使用ObjectBox提供的ToMany类创建关联关系。

2、在数据库bean里面添加非基础数据类型的数据,需要使用ObjectBox提供的ToOne或者ToMany类进行包装,否则无法生成MyObjectBox类。

3、数据库bean中的属性一定是 Pubilc

数据库bean的属性如果是private,会无法编译完成。只能设置为public。

4、保持objectbox-models/default.json唯一

default.json中保存的是Objectbox数据库所有现存字段的id值,对于Objectbox管理数据库而言非常重要。在合作开发中,多个人的编译结果最好以其中一人的为准。否则数据库不能正常使用。default.json原文是这样说的

default.json:
"_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.",

"_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.",

"_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.",

三、使用:

我自己写的demo:https://gitee.com/lyyon/DialogAndDatabase.git

使用时特别注意:

1、类上面可以打@Entity,如果是基类则打@BaseEntity。
2、一定要有一个@Id,类型为Long的属性,用于自增属性(也可以指定值用@Id(assignable = true))。
3、kotlin中的data class一定要有默认值,不然可能会找不到默认的构造方法。
4、如果某个字段不想序列化到数据库中可以打上:@Transient标签,从kotlin里或者objectBox中导入的都可以。

1、将ObjectBox Gradle插件添加到您的根目录中 build.gradle:

buildscript {
    ext.objectboxVersion = "3.5.1"
    repositories {        
        mavenCentral()    
    }
    dependencies {
        classpath("io.objectbox:objectbox-gradle-plugin:$objectboxVersion")
    }
}

2、App的build.gradle添加

// Using plugins syntax:
plugins {
    id("io.objectbox") // Add after other plugins.
}
// 将这句话放在末尾,不然会出问题
// Or using the old apply syntax:
apply plugin: "io.objectbox" // Add after other plugins.

3、Application的初始化

注意:在MyObjectBox对象之前一定要先创建一个实体,否则MyObjectBox找不到。

1、首先构建一个User对象

@Entity
class User {
    //assignable= true可以手动指定id值,出现相同会替换;不写这个给id赋值会报错
    @Id(assignable = true)
    var id: Long = 0
    var name: String = ""
    var sex: Long = 0
    var desc: String = ""
}

第一次put数据时报错信息:ID is higher or equal to internal ID sequence: 12345 (vs. 1). Use ID 0 (zero).

@Id(assignable = true)是指在使用BoxStore的put方法时,允许将已经存在的对象的id重新赋值。如果不加这个注解,则在put方法中尝试重新赋值id会抛出异常。

注意:操作完后,一定要重新编译,否则找不到MyObjectBox。

2、MyApplication 初始化

import android.app.Application
import android.content.Context
import com.sht.demo.bean.MyObjectBox
import io.objectbox.BoxStore

class MyApplication : Application() {
    companion object {
        //上下文
        var appContext: Context? = null

        //数据库
        var boxStore: BoxStore? = null
    }

    override fun onCreate() {
        super.onCreate()
        appContext = this

        initObjectBox()
    }

    /**
     * 初始化数据库
     */
    private fun initObjectBox() {
        //MyObjectBox找不到,必须先创建一个对象,然后重新编译,才可以
        boxStore = MyObjectBox.builder().androidContext(this).build()
    }
}

3、数据更新。

注意:更新数据(如果直接插入更新的对象(所有的字段都会被替换掉),有些字段没有值会覆盖掉)

1、先查询到数据
2、对查询到的数据字段进行更新
3、查询不到,直接插入

1、插入数据

// 插入数据
   btnAdd1.setOnClickListener {
                var user = User()
                user.id = 123L
                user.name = "小明"
                user.sex = 18
                user.desc = "啊哈哈哈或或哈或或"
               var result =  ObjectBoxUtils.addData(user,User::class.java)
                Log.d("lyy","插入数据1:${result}")
                queryAllData()
            }

2、更新数据

// 更新数据
  btnUpdate?.setOnClickListener {
                var user = User()
                user.id = 123L
                user.desc = "更改后的表述"
                var result =  ObjectBoxUtils.addData(user,User::class.java)
                Log.d("lyy","更改数据:${result}")
                queryAllData()
            }

3、打印结果:

com.sht.myapplication1               D  插入数据1:123
com.sht.myapplication1               D  id: 111  name: 小刚  sex: 8  desc: 
 com.sht.myapplication1               D  id: 123  name: 小明  sex: 18  desc: 啊哈哈哈或或哈或或 

com.sht.myapplication1               D  更改数据:123
com.sht.myapplication1               D  id: 111  name: 小刚  sex: 8  desc: 
com.sht.myapplication1               D  id: 123  name:   sex: 0  desc: 更改后的表述

总结:因为插入数据和更新数据是同一个put()方法,如果你new User()类,只给desc 赋值,其它字段(name和sex的值就会为空),所以,我们应该先查到对象,然后更新查到对象的一个字段。

推荐例子:

  /**
     * 更新数据(如果直接插入更新的对象,有些字段没有值会覆盖掉)
     * 1、先查询到数据
     * 2、对查询到的数据字段进行更新
     * 3、查询不到,直接插入
     */
    fun updateData(o: User, c: Class<User>) {
        try {
            val boxStore: BoxStore? = init()
            if (boxStore != null && !boxStore.isClosed) {
                //1、先查询到数据
                val box: Box<User> = boxStore.boxFor(User::class.java)
                val list: MutableList<User> = box.query().equal(User_.id, o.id).build().find()
                var localBean = list.getOrNull(0)
                //2、对查询到的数据字段进行更新
                localBean?.let {
                    localBean.desc = o.desc
                    boxStore.boxFor<User>(c).put(localBean)
                }?: kotlin.run {
                    //3、查询不到,直接插入
                    boxStore.boxFor<User>(c).put(o)
                }
            }
        } catch (e: Throwable) {
            Log.d("lyy", "error:${e.printStackTrace()}")
        }

    }

4、Kotlin 工具类封装

package com.sht.demo.tools

import android.util.Log
import com.sht.demo.MyApplication
import com.sht.demo.bean.MyObjectBox
import com.sht.demo.bean.User
import com.sht.demo.bean.User_
import io.objectbox.Box
import io.objectbox.BoxStore

/***
 * 数据库封装
 */
object ObjectBoxUtils {

    /**
     * 初始化数据库
     */
    var boxStore: BoxStore? = null
    fun init(): BoxStore? {
        try {
            boxStore = MyApplication.boxStore
            if (boxStore == null) {
                boxStore =
                    MyObjectBox.builder().androidContext(MyApplication.appContext).build()
                MyApplication.boxStore = boxStore
            }
        } catch (e: Exception) {
        }
        return boxStore
    }

    /**
     * 重启数据库
     * 删除本地数据库后,需要重新创建
     */
    fun  restartBoxStore(){
         boxStore = MyObjectBox.builder().androidContext(MyApplication.appContext).build()
        MyApplication.boxStore = boxStore
    }

    /**
     * 添加数据
     */
    fun <Any> addData(o: Any, c: Class<Any>): Long {
        try {
            val boxStore: BoxStore? = init()
            if (boxStore != null && !boxStore.isClosed) {
                return boxStore.boxFor<Any>(c).put(o)
            }
        } catch (e: Throwable) {
            Log.d("lyy", "error:${e.printStackTrace()}")
        }
        return 0
    }

    /**
     * 更新数据(如果直接插入更新的对象,有些字段没有值会覆盖掉)
     * 1、先查询到数据
     * 2、对查询到的数据字段进行更新
     * 3、查询不到,直接插入
     */
    fun updateData(o: User, c: Class<User>) {
        try {
            val boxStore: BoxStore? = init()
            if (boxStore != null && !boxStore.isClosed) {
                //1、先查询到数据
                val box: Box<User> = boxStore.boxFor(User::class.java)
                val list: MutableList<User> = box.query().equal(User_.id, o.id).build().find()
                var localBean = list.getOrNull(0)
                //2、对查询到的数据字段进行更新
                localBean?.let {
                    localBean.desc = o.desc
                    boxStore.boxFor<User>(c).put(localBean)
                }?: kotlin.run {
                    //3、查询不到,直接插入
                    boxStore.boxFor<User>(c).put(o)
                }
            }
        } catch (e: Throwable) {
            Log.d("lyy", "error:${e.printStackTrace()}")
        }

    }


    /**
     * 添加数组
     */
    fun <T> addData(list: List<Any>?, c: Class<Any>?) {
        try {
            //MyToash.Log("home","---oo: "+oo.size());
            val boxStore = init()
            if (boxStore != null && !boxStore.isClosed) {
                boxStore.boxFor<Any>(c).put(list)
            }
        } catch (e: java.lang.Exception) {
            Log.d("lyy", "---error:$e")
        }
    }

    /**
     * 获取全部对象数据
     */
    fun <Any> getAllData(clazz: Class<Any>?): List<Any>? {
        try {
            val boxStore = init()
            if (boxStore != null && !boxStore.isClosed) {
                val box: Box<Any> = boxStore.boxFor<Any>(clazz)
                return box.all
            }
        } catch (e: java.lang.Exception) {
        }
        return ArrayList()
    }

    /**
     * 条件查询
     */
    fun getUserData(): List<User>? {
        try {
            val boxStore = init()
            if (boxStore != null && !boxStore.isClosed) {
                val box: Box<User> = boxStore.boxFor(User::class.java)
                return box.query().equal(User_.sex, 1).build().find()
            }
        } catch (e: java.lang.Exception) {
        }
        return ArrayList<User>()
    }

    /**
     * 查询单个数据
     */
    fun getUser(id: Long): User? {
        try {
            val boxStore = init()
            if (boxStore != null && !boxStore.isClosed) {
                val box: Box<User> = boxStore.boxFor(User::class.java)
                return box[id]
            }
        } catch (e: java.lang.Exception) {
        }
        return null
    }

    /**
     * 删除数据单个数据1
     */
    fun deleteUserData(id: Long): Boolean {
        try {
            val boxStore = init()
            if (boxStore != null && !boxStore.isClosed) {
                val box: Box<User> = boxStore.boxFor(User::class.java)
                return box.remove(id)
            }
        } catch (e: java.lang.Exception) {
        }
        return false
    }


    /**
     * 删除数据单个数据2
     */
    fun <Any> deleteData(o: Any, clazz: Class<Any>?) {
        try {
            val boxStore = init()
            if (boxStore != null && !boxStore.isClosed) {
                val box: Box<Any> = boxStore.boxFor<Any>(clazz)
                box.remove(o)
            }
        } catch (e: java.lang.Exception) {
        }
    }

    /**
     * 删除列表数据
     */
    fun <T> deletALLeData(o: List<Any>?, clazz: Class<Any>?) {
        try {
            val boxStore = init()
            if (boxStore != null && !boxStore.isClosed) {
                val box: Box<Any> = boxStore.boxFor<Any>(clazz)
                box.remove(o)
            }
        } catch (e: java.lang.Exception) {
        }
    }


}



4、Java 工具类封装

import com.youjiakeji.yjkjreader.base.BWNApplication;
import com.youjiakeji.yjkjreader.model.Audio;
import com.youjiakeji.yjkjreader.model.AudioChapter;
import com.youjiakeji.yjkjreader.model.AudioChapter_;
import com.youjiakeji.yjkjreader.model.Audio_;
import com.youjiakeji.yjkjreader.model.Book;

import com.youjiakeji.yjkjreader.model.BookChapter;


import com.youjiakeji.yjkjreader.model.BookChapter_;
import com.youjiakeji.yjkjreader.model.BookMarkBean_;
import com.youjiakeji.yjkjreader.model.Book_;
import com.youjiakeji.yjkjreader.model.Comic;
import com.youjiakeji.yjkjreader.model.ComicChapter;
import com.youjiakeji.yjkjreader.model.ComicChapter_;
import com.youjiakeji.yjkjreader.model.Comic_;
import com.youjiakeji.yjkjreader.model.Downoption;

import com.youjiakeji.yjkjreader.model.Downoption_;
import com.youjiakeji.yjkjreader.model.BookMarkBean;
import com.youjiakeji.yjkjreader.model.MyObjectBox;
import com.youjiakeji.yjkjreader.ui.utils.MyToash;


import java.util.ArrayList;
import java.util.List;

import io.objectbox.Box;
import io.objectbox.BoxStore;

/**
 * 书籍数据库管理类
 */
public class ObjectBoxUtils {

    public static BoxStore init() {
        BoxStore boxStore = null;
        try {
            boxStore = BWNApplication.applicationContext.getBoxStore();
            if (boxStore == null) {
                boxStore = MyObjectBox.builder().androidContext(BWNApplication.applicationContext).build();
                BWNApplication.applicationContext.setBoxStore(boxStore);
            }
        } catch (Exception e) {
        }
        return boxStore;
    }

    /**
     * 添加数据
     */
    public static <T> long addData(T o, Class c) {
        //MyToash.Log("home",c.getName());
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                return boxStore.boxFor(c).put(o);
            }
        } catch (Throwable e) {
        }
        return  0;
    }

    public static <T> void addData(List<T> oo, Class c) {
        try {
            //MyToash.Log("home","---oo: "+oo.size());
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                boxStore.boxFor(c).put(oo);
            }
        } catch (Exception e) {
            MyToash.Log("lyy", "---error:"+e.toString());
        }
    }

    public static <T> List<T> getAllData(Class clazz) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<T> box = boxStore.boxFor(clazz);

                return box.getAll();
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    public static List<Book> getBookShelfData() {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<Book> box = boxStore.boxFor(Book.class);
                List<Book> joes = box.query().equal(Book_.is_collect, 1).build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    public static List<Downoption> getDownoptionsfData(long book_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<Downoption> box = boxStore.boxFor(Downoption.class);
                List<Downoption> joes = box.query().equal(Downoption_.book_id, book_id).build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    public static List<BookChapter> getBookChapterItemfData(long book_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<BookChapter> box = boxStore.boxFor(BookChapter.class);
                List<BookChapter> joes = box.query().equal(BookChapter_.book_id, book_id).build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    public static List<ComicChapter> getcomicDownOptionList(long comic_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<ComicChapter> box = boxStore.boxFor(ComicChapter.class);
                List<ComicChapter> joes = box.query()
                        .equal(ComicChapter_.comic_id, comic_id)
                        .equal(ComicChapter_.downStatus, 1)
                        .build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    public static List<Comic> getyetDownComicList() {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<Comic> box = boxStore.boxFor(Comic.class);
                List<Comic> joes = box.query()
                        .notEqual(Comic_.down_chapters, 0)
                        .build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    public static List<ComicChapter> getComicChapterItemfData(long comic_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<ComicChapter> box = boxStore.boxFor(ComicChapter.class);
                List<ComicChapter> joes = box.query().equal(ComicChapter_.comic_id, comic_id).build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    public static List<AudioChapter> getAudioChapterItemfData(long audio_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<AudioChapter> box = boxStore.boxFor(AudioChapter.class);
                List<AudioChapter> joes = box.query().equal(AudioChapter_.audio_id, audio_id).build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    public static ComicChapter getComicChapter(long id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<ComicChapter> box = boxStore.boxFor(ComicChapter.class);
                return box.get(id);
            }
        } catch (Exception e) {
        }
        return null;

    }

    public static Book getBook(long id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<Book> box = boxStore.boxFor(Book.class);
                return box.get(id);
            }
        } catch (Exception e) {
        }
        return null;
    }

    public static BookChapter getBookChapter(long chapter_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<BookChapter> box = boxStore.boxFor(BookChapter.class);
                return box.get(chapter_id);
            }
        } catch (Exception e) {
        }
        return null;
    }

    public static Comic getComic(long id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<Comic> box = boxStore.boxFor(Comic.class);
                return box.get(id);
            }
        } catch (Exception e) {
        }
        return null;
    }

    public static List<Comic> getComicShelfData() {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<Comic> box = boxStore.boxFor(Comic.class);
                List<Comic> joes = box.query().equal(Comic_.is_collect, 1).build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    public static List<Audio> getAudioShelfData() {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<Audio> box = boxStore.boxFor(Audio.class);
                List<Audio> joes = box.query().equal(Audio_.is_collect, 1).build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    //删除数据
    public static <T> void deleteData(Object o, Class clazz) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<T> box = boxStore.boxFor(clazz);
                box.remove((T) o);
            }
        } catch (Exception e) {
        }
    }

    //删除数据
    public static <T> void deletALLeData(List<T> o, Class clazz) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<T> box = boxStore.boxFor(clazz);
                box.remove(o);
            }
        } catch (Exception e) {
        }
    }

    public static Downoption getDownoption(long id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<Downoption> box = boxStore.boxFor(Downoption.class);
                Downoption joe = box.query().equal(Downoption_.id, id).build().findFirst();
                return joe;
            }
        } catch (Exception e) {
        }
        return null;
    }

    //删除数据
    public static void deleteDownoption(long id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<Downoption> box = boxStore.boxFor(Downoption.class);
                box.remove(id);
            }
        } catch (Exception e) {
        }
       /* try {
            Downoption downoption = getDownoption(id);
            deleteData(downoption, Downoption.class);
        } catch (Exception e) {
        }*/
    }

    public static List<BookChapter> getBookChapterData(long book_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<BookChapter> box = boxStore.boxFor(BookChapter.class);
                List<BookChapter> joes = box.query().equal(BookChapter_.book_id, book_id).build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    public static List<BookChapter> getBookChapterMoreChapter_id(long book_id, long Chapter_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<BookChapter> box = boxStore.boxFor(BookChapter.class);
                List<BookChapter> joes = box.query().equal(BookChapter_.book_id, book_id).build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    public static BookChapter getBookChapterFirstData(long book_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<BookChapter> box = boxStore.boxFor(BookChapter.class);
                BookChapter joes = box.query().equal(BookChapter_.book_id, book_id).build().findFirst();
                if (joes != null) {
                    return joes;
                }
                return joes;
            }
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * 删除数据
     */
    public static <T> void removeAllData(Class clazz) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<T> box = boxStore.boxFor(clazz);
                box.removeAll();
            }
        } catch (Exception e) {
        }
    }

    public static void removeAllBookChapterData(long book_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<BookChapter> box = boxStore.boxFor(BookChapter.class);
                box.remove(getBookChapterItemfData(book_id));
            }
        } catch (Exception w) {
        }
    }

    public static void removeAllComicChapterData(long comic_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<ComicChapter> box = boxStore.boxFor(ComicChapter.class);
                box.remove(getComicChapterItemfData(comic_id));
            }
        } catch (Exception e) {
        }
    }

    public static void removeAllAudioChapterData(long audio_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<AudioChapter> box = boxStore.boxFor(AudioChapter.class);
                box.remove(getAudioChapterItemfData(audio_id));
            }
        } catch (Exception e) {
        }
    }



    public static Audio getAudio(long id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<Audio> box = boxStore.boxFor(Audio.class);
                return box.get(id);
            }
        } catch (Exception e) {
        }
        return null;
    }

    public static List<AudioChapter> getAudioChapterData(long audio_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<AudioChapter> box = boxStore.boxFor(AudioChapter.class);
                List<AudioChapter> joes = box.query().equal(AudioChapter_.audio_id, audio_id).build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    public static AudioChapter getAudioChapter(long chapter_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<AudioChapter> box = boxStore.boxFor(AudioChapter.class);
                return box.get(chapter_id);
            }
        } catch (Exception e) {
        }
        return null;
    }

    public static List<Audio> getyetDownAudioList() {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<Audio> box = boxStore.boxFor(Audio.class);
                List<Audio> joes = box.query()
                        .notEqual(Audio_.down_chapters, 0)
                        .build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    /**
     * 添加书签
     */
    public static long addBookMarkBean(BookMarkBean bookMarkBean) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                return  boxStore.boxFor(BookMarkBean.class).put(bookMarkBean);
            }
        } catch (Exception e) {
        } catch (Error error) {
        }
        return  0;
    }

    /**
     * @return 获取全部书签列表
     */
    public static List<BookMarkBean> getBookMarkBeanList(long book_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<BookMarkBean> box = boxStore.boxFor(BookMarkBean.class);
                List<BookMarkBean> joes = box.query()
                        .equal(BookMarkBean_.book_id, book_id)
                        .build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    /**
     * @return 获取指定书签
     */
    public static BookMarkBean getBookMarkBean(long BookMarkBean_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<BookMarkBean> box = boxStore.boxFor(BookMarkBean.class);
                return box.get(BookMarkBean_id);
            }
        } catch (Exception e) {
        }
        return  null;
    }

    /**
     * 获取指定章节书签全部列表
     * @param chapter_id
     * @return
     */
    public static List<BookMarkBean> getChapterBookMarkBeanList(long chapter_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<BookMarkBean> box = boxStore.boxFor(BookMarkBean.class);
                List<BookMarkBean> joes = box.query()
                        .equal(BookMarkBean_.chapter_id, chapter_id)
                        .build().find();
                return joes;
            }
        } catch (Exception e) {
        }
        return new ArrayList<>();
    }

    /**
     * 删除书签
     * @param mark_id
     * @return
     */
    public static boolean removeMarkBean(long mark_id) {
        try {
            BoxStore boxStore = init();
            if (boxStore != null && !boxStore.isClosed()) {
                Box<BookMarkBean> box = boxStore.boxFor(BookMarkBean.class);
                return  box.remove(mark_id);
            }
        } catch (Exception e) {
        }
        return false;
    }
}

5、使用测试

class ObjectBoxActivity:AppCompatActivity() {
    var binding:ActivityObjectBoxBinding?=null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView<ActivityObjectBoxBinding>(this, R.layout.activity_object_box)

        binding?.apply {
            btnAdd1.setOnClickListener {
                var user = User()
                user.id = 123L
                user.name = "小明"
                user.sex = 18
                user.desc = "啊哈哈哈或或哈或或"
               var result =  ObjectBoxUtils.addData(user,User::class.java)
                Log.d("lyy","插入数据1:${result}")
                queryAllData()
            }

            btnAdd2.setOnClickListener {
                var user = User()
                user.id = 111L
                user.name = "小刚"
                user.sex = 8
                var result =  ObjectBoxUtils.addData(user,User::class.java)
                Log.d("lyy","插入数据2:${result}")
                queryAllData()
            }
            btnDelete1?.setOnClickListener {
                var id = 123L
                var result =  ObjectBoxUtils.deleteUserData(id)
                Log.d("lyy","删除数据1:${result}")
                queryAllData()
            }

            btnDelete2?.setOnClickListener {
                var user = User()
                user.id = 123L
                ObjectBoxUtils.deleteData(user,User::class.java)
                queryAllData()
            }
            btnUpdate?.setOnClickListener {
                var user = User()
                user.id = 123L
                user.name = "小明明"
                user.desc = "更改后的表述"
                user.sex = 10
                var result =  ObjectBoxUtils.addData(user,User::class.java)
                Log.d("lyy","更改数据:${result}")
                queryAllData()
            }
            btnQuerySingle?.setOnClickListener {
                var id = 123L
                var bean = ObjectBoxUtils.getUser(id)
                Log.d("lyy","id: ${bean?.id}  name: ${bean?.name}  sex: ${bean?.sex}")
            }
            btnQueryAll?.setOnClickListener {
                queryAllData()
            }
        }
    }


    fun  queryAllData(){
       var list =  ObjectBoxUtils.getAllData(User::class.java)
        list?.forEach {
            Log.d("lyy","id: ${it.id}  name: ${it.name}  sex: ${it.sex}  desc: ${it.desc}")
        }
    }

}

四、增删改查分析:

1、新增和更新(是同一个方法)

  fun <Any> addData(o: Any, c: Class<Any>): Long {
        try {
            val boxStore: BoxStore? = init()
            if (boxStore != null && !boxStore.isClosed) {
                return boxStore.boxFor<Any>(c).put(o)
            }
        } catch (e: Throwable) {
            Log.d("lyy", "error:${e.printStackTrace()}")
        }
        return 0
    }

2、删除

图片.png
 /**
     * 删除数据单个数据1
     */
    fun deleteUserData(id: Long): Boolean {
        try {
            val boxStore = init()
            if (boxStore != null && !boxStore.isClosed) {
                val box: Box<User> = boxStore.boxFor(User::class.java)
                return box.remove(id)
            }
        } catch (e: java.lang.Exception) {
        }
        return false
    }


    /**
     * 删除数据单个数据2
     */
    fun <Any> deleteData(o: Any, clazz: Class<Any>?) {
        try {
            val boxStore = init()
            if (boxStore != null && !boxStore.isClosed) {
                val box: Box<Any> = boxStore.boxFor<Any>(clazz)
                box.remove(o)
            }
        } catch (e: java.lang.Exception) {
        }
    }

    /**
     * 删除列表数据
     */
    fun <T> deletALLeData(o: List<Any>?, clazz: Class<Any>?) {
        try {
            val boxStore = init()
            if (boxStore != null && !boxStore.isClosed) {
                val box: Box<Any> = boxStore.boxFor<Any>(clazz)
                box.remove(o)
            }
        } catch (e: java.lang.Exception) {
        }
    }

3、查询

query的参考文档:https://docs.objectbox.io/queries

  /**
     * 获取全部对象数据
     */
    fun <Any> getAllData(clazz: Class<Any>?): List<Any>? {
        try {
            val boxStore = init()
            if (boxStore != null && !boxStore.isClosed) {
                val box: Box<Any> = boxStore.boxFor<Any>(clazz)
                return box.all
            }
        } catch (e: java.lang.Exception) {
        }
        return ArrayList()
    }

    /**
     * 条件查询
     */
    fun getUserData(): List<User>? {
        try {
            val boxStore = init()
            if (boxStore != null && !boxStore.isClosed) {
                val box: Box<User> = boxStore.boxFor(User::class.java)
                return box.query().equal(User_.sex, 1).build().find()
            }
        } catch (e: java.lang.Exception) {
        }
        return ArrayList<User>()
    }

    /**
     * 查询单个数据
     */
    fun getUser(id: Long): User? {
        try {
            val boxStore = init()
            if (boxStore != null && !boxStore.isClosed) {
                val box: Box<User> = boxStore.boxFor(User::class.java)
                return box[id]
            }
        } catch (e: java.lang.Exception) {
        }
        return null
    }

val query = userBox.query()
        .equal(User_.firstName, "Joe")
        .greater(User_.yearOfBirth, 1970)
        .startsWith(User_.lastName, "O")
        .build()
val youngJoes = query.find()
//query.close() // Or keep the query instance to re-use it
val query = userBox.query(User_.firstName.equal("Joe")).build()
val joes = query.find()
query.close()
// equal AND (less OR oneOf)
val query = box.query(
        User_.firstName equal "Joe"
                and (User_.age less 12
                or (User_.stamp oneOf longArrayOf(1012))))
        .order(User_.age)
        .build()

4、清空数据库数据

1、方式1:

//是清除了表格中的所有数据,数据表和结构都在,不需要重启
MyApplication.boxStore?.removeAllObjects()

2、方式2(必须重启才能继续使用数据库):
和方法3一样

    //先关闭了数据库,然后清除(无法进行操作了)
      MyApplication.boxStore?.close()
      //这个方法只会删除存储在 Box 中的所有文件。
      MyApplication.boxStore?.deleteAllFiles()
     //重启数据库
      ObjectBoxUtils. restartBoxStore()

它会删除所有与该数据库相关的文件,包括数据文件、索引文件、锁文件等。

3、方式3(必须重启才能继续使用数据库):

//先关闭了数据库,然后清除(无法进行操作了)
MyApplication.boxStore?.close()
//清除这个数据库,重新创建
MyApplication.boxStore?.deleteAllFiles()
//重启数据库
ObjectBoxUtils. restartBoxStore()

objectBox中的deleteAllFiles()方法是用于删除所有数据库文件的方法。它会删除所有与该数据库相关的文件,包括数据文件、索引文件、锁文件等。这个方法通常用于清空整个数据库,或者在重新创建数据库时使用。需要注意的是,使用该方法会永久删除所有数据,因此在使用前需要谨慎考虑。

4、方式4(重启数据库)

    /**
     * 重启数据库
     * 删除本地数据库后,需要重新创建
     */
    fun  restartBoxStore(){
         boxStore = MyObjectBox.builder().androidContext(MyApplication.appContext).build()
         MyApplication.boxStore = boxStore
    }

5、数据库的位置

图片.png

6、查看数据库里的数据

MyApplication.boxStore?.startObjectBrowser()

查看方式1:
查看方式2:

相关文章

网友评论

    本文标题:ObjectBox 最详细的使用指南

    本文链接:https://www.haomeiwen.com/subject/sdjvjdtx.html