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 classes;
/--------------------------------------------------/

    //...

}


@Entity
public class Class{
    @Id long id;

    long gradeId;

    @Relation
    Grade grade;

    //...
}

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

@Entity
public class Grade {
    @Id long id;

    @Relation(idProperty = "gradeId")
    List classes;

    //...

}


@Entity
public class Class{
    @Id long id;

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

    @Relation
    Grade grade;

    //下面的代码是一对多对应到Student
    @Relation(idProperty = "classId")
    List 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()

后记

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

你可能感兴趣的:(ObjectBox在Android中的使用)