ObjectBox在Android中的使用

ObjectBox官网

提要

因为最近做个小项目需要用到数据库,考虑使用ObjectBox。因为还是测试版,网上真实使用该数据库的相关资料也很少。根据官方文档遇到了一些问题,所以就想找时间记录下自己的经验,供大家参考。

本文内容摘要:
  1. 正确的初始化及正常使用
  2. 数据库关联

简单介绍:

  • greenrobot公司出品,greenDao、EventBus同样出自该公司。
  • ObjectBox是该公司针对性能提升新出的数据库,据官网称优于对比测试的所有嵌入型数据库5-15倍。
  • 当前可在Android、Linux、Windows平台上使用,MacOS和iOS随后跟进。本文为Android平台使用经验。
  • 目前最新版本是0.99 (2017.3.07)。

使用

一、初始化

首先:添加依赖

直接从官网拿了,照着操作。
注意:不像其他很多需要初始化的库,ObjectBox在这一步完成后不能直接在Application中进行初始化。
ps:当初没注意文档有没有特殊说明需要先Build,现在是有特殊说明的。当时我是直接去初始化。一直找不到MyObjectBox这个类,还以为是自己依赖添加有问题。后来看到Alex_Cin的文章才注意到这一点。文章不知道为什么他已经删了。真的帮到我了,感谢。

buildscript {
    repositories {
        jcenter()
        mavenCentral()
        maven {
            url "http://objectbox.net/beta-repo/"
        }
    }
    dependencies {
        classpath 'io.objectbox:objectbox-gradle-plugin:0.9.9'
    }
}
 
apply plugin: 'com.android.application'
apply plugin: 'io.objectbox'
 
repositories {
    jcenter()
    mavenCentral()
    maven {
        url "http://objectbox.net/beta-repo/"
    }
}
 
dependencies {
    compile 'io.objectbox:objectbox-android:0.9.9'
}
然后:生成实体类,创建一个bean类完成该步骤后需build一下project生成ObjectBox需要的类

bean类中主要是两个注解,@Entity和@Id。

  1. @Entity加在Bean类上,@Id为必需的一个属性。
  2. 我不需要id这个属性?还有id我该怎么设置?其实你不用管。
    • 在ObjectBox数据库中,0和-1是特殊的不可作为id的值。id为0时表示对象未保存到数据库,会自动为其分配一个id值。默认情况类似id从1开始自增长。因为long类型默认值为0,所以大部分情况你可以不用管id这个属性。
    • 最高检查。如果你试图将id值大于当前数据库中id最大值的对象放入数据库,ObjectBox会报错。
    • 从其他地方获取id,比如服务器,可以使用@Id(assignable = true),最高检查也不会生效。
  3. 简单代码示例,直接从官网拿的。
    @Entity
    public class User {
 
        @Id
        private long id;
        ...
    }
最后:真正的初始化

一步一步来的话,就很顺利,这个也没什么好说的。

//自定义的Application里,放一个静态BoxStore对象,用下面的代码赋值。
boxStore = MyObjectBox.builder().androidContext(YourApplication.this).build();

二、增删查改

  1. 获取到某个数据库,比如获取实体类A的相关数据库:aBox = ((App) getApplication()).getBoxStore().boxFor(A.class);
  2. 利用aBox,ObjectBox提供了一系列方便易用的Api。
    • 增:.put(),参数可以是集合、也可以是单个A对象,单个对象时该Api返回放入数据库后的对象id。
    • 删:.remove()系列Api,参数可以是对象、对象集合、对象id、对象id集合等,你还可以直接使用removeAll()来清空某个对象的数据库。不同于一些数据库会返回被删除对象,ObjectBox的删除操作均返回void
    • 查:使用.query()获取一个QueryBuilder,使用builder.equal()进行设置匹配。该步可以调用startWith()等Api进行精确设置。之后进行build()获取一个Query对象,然后就可以执行各种花式操作了。下面是Query的一些Api。关于整个查询可以参照官方详细查询操作。注意,查询中设置属性应该使用生成类的属性。比如User生成类为User_,要使用到年龄属性可以使用User_.age()。
      • 查找:find()、findfirst()、findUnique()。如名字,最后一个是从匹配结果里找出一个独特的,没有或者有多个都返回null。
      • 精确查找设置:query.setParameter()
      • 分页查询:find(long offset,long limit)方法。offset为偏移量,就是从哪开始,但不会返回这个结果,比如设置10就返回从11开始的数据。limit为最多返回多少数据。
      • 直接返回一些计算过的值,该类Api以属性为参数,比如想知道所有用户中年龄最大的可以使用max(User_.age),此外还有min/minDouble、sum/sumDouble、avg、maxDouble等,见名知意。double后缀返回Double类型值。
      • 从数据库中删除匹配的对象,可以直接使用query.remove()。

三、关联

问题是这样的:
在学校里一个年级对应有很多班,每个班又有很多学生。这时我需要把整个年级作为一个对象存储到数据库,使用ObjectBox需要怎么操作?

第一步,生成基本类

这里生成三个类,Grade.classClass.classStudent.class。并应用@Entity、@Id这些必要的注解。以及一些与其他实体类不相干的属性可以设置了。现在我们的类大概是这样的(做了整合,真实工程中当然是分开写的)

@Entity
public class Grade {
    @Id long id;
    //...
}

@Entity
public class Class {
    @Id long id;
    //...
}
@Entity
public class Student {
    @Id long id;
    //...
}

第二步,做关联

主要是一个注解@Relation

简单提下一对一

我们假设一个年级只能有一个班,则年级和班的类可以写成下面这样

@Entity
public class Grade {
    @Id long id;
    //...
}


@Entity
public class Class{
    @Id long id;

    long gradeId;

    @Relation
    Grade grade;
/--------------------------------------------------/

}

build之后可以通过setGradeId()setGrade()来设置对应关系。效果一样。

一对多

比如,六年级有三个班

  • 对于这些班来说,需要一个标记来标识自己是哪个年级的。上边的一对一就是做到了这一点。
  • 对于六年级这个年级来说,需要有一个集合属性来保存多个Class。这时可以通过给集合里的所有Class设置统一的gradeId,来形成一对多的关系。我们首先添加一个classes的集合属性到Grade类,然后可以通过为其添加@Relation(idProperty = "gradeId")注解来实现该功能。

这时候Grade.classClass.class类的代码大概是这样的:

@Entity
public class Grade {
    @Id long id;

/--------------------------------------------------/
    @Relation(idProperty = "gradeId")
    List<Class> classes;
/--------------------------------------------------/

    //...

}


@Entity
public class Class{
    @Id long id;

    long gradeId;

    @Relation
    Grade grade;

    //...
}

所以,最后我们的代码应该是这样子的:

@Entity
public class Grade {
    @Id long id;

    @Relation(idProperty = "gradeId")
    List<Class> classes;

    //...

}


@Entity
public class Class{
    @Id long id;

    //下面两句代码是一对一对应到Grade
    long gradeId;

    @Relation
    Grade grade;

    //下面的代码是一对多对应到Student
    @Relation(idProperty = "classId")
    List<Student> students;
    //...
}


@Entity
public class Student{
    @Id long id;

    //下面两句代码是一对一对应到Class
    long classId;

    @Relation
    Class class;

    //...
}
注意

关联相关的属性,不要手动写getter/setter方法,当你build工程的时候,它会自动生成。如果你手动写了getter/setter会报错。

If you would like to keep it, it should be explicitly marked with @Keep annotation. Otherwise please mark it with @Generated annotation

删除自己写的即可。

第三步,代码中使用

  1. 添加,比如往六年级grade6添加一个班级class1
    1. 首先如果你没有手动为grade6设置id,应该保证你是从数据库中取出的数据,或者先将grade6使用put()放入gradeBox,并获取到返回值id。
    2. 关联。给class1设置gradeIdclass1.setGradeId(gradeId);
    3. 存放。将class1存到数据库,classBox.put(class1)
  2. 删除,调用box.remove()系列Api即可。
  3. 删除全部,如移除六年级grade6所有班级可以这样grade6.resetClasses()

后记

我目前用到的大概就是这些内容,希望能帮到你。

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

推荐阅读更多精彩内容