ObjectBox-Java (android)使用手册

前前言

本篇主要是方便自己记忆所写, 基本是撸完官方文档后的笔记

前言

ObjectBox是一款由greenrobot出的基于noSql的ORM数据库, 但又支持表关系的定义以及事务的处理, 另外在性能上有着非常卓越的表现
(关于性能比较, 可以看这篇,
同时可以接入rxJava的扩展库, 并与google最新出的框架组件(Android Architecture Components)中的LiveData结合使用, 支持Kotlin.
目前版本更新到1.2.1

依赖

  1. 在项目根目录的gradle添加它的依赖仓库地址
buildscript {
    ext.objectboxVersion = '1.2.1'
    repositories {
        jcenter()
        maven { url "http://objectbox.net/beta-repo/" }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath "io.objectbox:objectbox-gradle-plugin:$objectboxVersion"
    }
}
allprojects {
    repositories {
        jcenter()
        maven { url "http://objectbox.net/beta-repo/" }
    }
}
  1. 在应用项目模块(app module)中添加插件
apply plugin: 'com.android.application'
apply plugin: 'io.objectbox'

基本使用

  1. 准备ObjectBox对象单例并实例化, 可以放在application的onCreate()
// MyObjectBox类文件这时候是引用不到, 它是根据实体类自动生成(build), 用来设置BoxStore对象
boxStore = MyObjectBox.builder().androidContext(applicationContext).build();
  1. 添加一个对象类, 添加@Entity注解, 进行表映射
@Entity
public class User{
    // 主键, 必须有, 并且必须是long类型
    @Id
    private long id;

    private String userName;
    private int userAge;
    // 必须有
    public User(){}
}

P.S 这时候记得build一下, MyObjectBox就自动生成了

  1. 这时候我们就可以通过Box<User>对象来针对这张表做增删改查工作了
Box<User> userBox = boxStore.boxFor(User.class).build();

增删改查

Box分别有put 添加or修改, query 查找, remove 移除 等开放API可调用.
在调用put时, 当Entity的Id不设置, 则会自动为其赋值, 并新增数据. 当有设置Id, 并在表内有对应Id, 则会被覆盖, 相当于更新对应数据.
另外关于@Id,有几点需要注意:

  • 0-1(0xFFFFFFFFFFFFFFFF)不能作为Id的值使用
  • 0 或者null(如果类型是Long, 但不建议使用Long, 使用long的速度会更快)会是通知永远新增一笔新数据
  • 如果put一个id比当前最大id大的对象, ObjectBox可能会抛出异常
  • 如果要自己分配id, 可以使用注解@Id(assignable = true)

相关的方法, 可以参考JavaDoc中关于BoxQueryBuilder类中的方法

注解

除了本文其他地方已提到的注解, 补充几个比较大概率会用到的, 其他的建议大家可以看看JavaDoc中的io.objectbox.annotation包:

@Entity
public class User{
    @Id
    private long id;

    @Index
    private String uid;
    @NameInDb("userName")
    private String name;
    @Transient
    private boolean country;
}
  • @Index: 因为在ObjectBox中主键是必须设置为long类型的id, 当我们业务上需要另外主键时, 可以再标注@Index, 在ObjectBox中查询时根据他标注的字段来查询, 会加快查询速度
  • @NameInDb: 字段在数据库中的命名
  • @Transient: 忽略字段, 不在表中生成

数据迁移

ObjectBox可以实现大部分的数据迁移自动化, 当我们要删除或者新增一个字段的时候, 针对数据库我们是不需要做任何操作的.

但是当我们需要重命名字段名或者表名, 或者需要更改字段类型时, 我们需要使用@Uid通知ObjectBox

下面我们会分别举两个例子:

  1. 重命名操作, 实体类重命名或者字段重命名操作流程都一样, 区别只在于是在在哪里放@Uid, 以实体类重命名为例:
  • 在类名上添加@Uid
@Entity
@Uid
public class User{
    @Id
    private long id;

    private String userName;
    private int userAge;

    public User(){}
}
  • rebuild一下, 在Gradle Console中会找到下面类似一段
错误: [ObjectBox] UID operations for entity "User2":
 [Rename] apply the current UID using @Uid(6966387148602341622L) - [Change/reset] apply a new UID using @Uid(2383770126231565339L)
1 个错误
  • copy [Rename]@Uid值6966387148602341622L, 并针对实体类进行重命名
@Entity
@Uid(6966387148602341622L)
public class User2{
    @Id
    private long id;

    private String userName;
    private int userAge;

    public User2(){}
}
  • 重新编译, 就已经迁移成功, 这时候@Uid(6966387148602341622L)这条代码就没有用了, 相关记录会在objectbox-models/default.json中体现
  1. 变更字段类型, 要注意的是, 会导致原类型字段Column的数据会被清空, 大体流程与重命名流程大致相同, 但是赋值的@Uid 需要使用的是[Change/reset]的值, 表示是一个新字段.

P.S 前文提到了objectbox-models/default.json这个JSON文件, 这个文件相当于是我们做Migration时处理的文件记录, 所以是需要加入VCS控制

关系

  • 以后补充

事务

ObjectBox的所有操作都是在事务中运行的, 只是这个对我们来说是透明的, 我们不需要关注, 但是当我们需要进行多个操作的时候, 通过显示事务来控制, 可以大大提高app的效率和一致性.
BoxStore中, 提供了四个方法来执行显示事务:

  • runInReadTx : 在事务中运行给定的Runnable, 不可并发处理
  • runIxTx : 只读事务, 可以并发处理
  • runInTxAsync : 在单独的线程中运行, 事务完成后会回调callback(可能为空)
  • callInTx : 和runIxTx类似, 不过允许返回值并可以抛出一个异常

要注意的是, 事务的提交开销较大, 所以在使用隐式事务时, 譬如大批量调用put时, 我们需要统一写到一个事务里去提交

for(User user: userList){
  user.plusAge();
  box.put(user);
}

以上的demo我们应该优化为下面这种:

for(User user: userList){
 user.plusAge();
}
box.put(userList);

数据库查看

  1. 在项目app gradle文件中, 必须在'io.objectbox'插件apply之前依赖一下代码
debugCompile "io.objectbox:objectbox-android-objectbrowser:1.2.1"
releaseCompile "io.objectbox:objectbox-android:1.2.1"
  1. 清单文件申请权限
<uses-permission android:name="android.permission.INTERNET"/>
  1. 然后在BoxStore构建之后, 加入以下代码
if(BuildConfig.DEBUG){
            new AndroidObjectBrowser(boxStore).start(this);
  }

运行后, 就可以从设备的通知栏点击进入查看数据库, 也可以通过在cmd中输入adb forward tcp:8090 tcp:8090, 打开浏览器, 输入http://localhost:8090/index.html 网址查看

后记

关于它和rxJava如何使用, 如何做数据的观测, 以及和LiveData的搭配使用, 鉴于目前篇幅过长, 而且LiveData我目前还没有玩过, 所以暂时不写. 后续可能会新补一篇.
相关Demo可以看这里

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352