Java - Android GreenRobot新作:Obje

作者: Cosecant | 来源:发表于2017-05-04 10:34 被阅读328次

    GreenRobot新作 - ObjectBox

    ​ObjectBox是GreenRobot的新作NoSQL存储系统。GreenRobot称它是目前性能最好且易用的 NoSQL 数据库,且优于其它数据库 5~15 倍的性能。

    特性

    首先为什么我们需要这个数据库, GreenRobot 介绍了它的5个特性:

    • : 比测试过的其它数据库快 5~15 倍
    • 面向对象的 API : 没有 rows、columns 和 SQL,完全面向对象的 API
    • 即时的单元测试 : 因为它是跨平台的,所以可以在桌面运行单元测试
    • 简单的线程 : 它返回的对象可以在任何线程运转
    • 不需要手动迁移 : 升级是完全自动的,不需要关心属性的变化以及命名的变化

    如何配置与使用呢?

    首先在android项目根目录的build.gradle文件中配置:

    buildscript {
        repositories {
            jcenter()
            mavenCentral()
            maven {
                url "http://objectbox.net/beta-repo/"
            }
        }
        dependencies {
            classpath 'io.objectbox:objectbox-gradle-plugin:0.9.11'
        }
    }
    

    App目录下build.gradle应该这样配置:

    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.11'
    }
    

    配置完后,你可能会得到以下一段错误提示:

    Warning:Conflict with dependency 'com.google.code.findbugs:jsr305'. Resolved versions for app (3.0.1) and test app (2.0.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details.

    解决方案如下, app的build.gradle下做配置:

    android{
      ...
        configurations.all {
        resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
        }
      ...
    }
    

    那么我们又如何使用ObjectBox呢?

    在 Application 中初始化

    // 在 Application 中初始化
    boxStore = MyObjectBox.builder().androidContext(App.this).build();
    

    Entity

    Entity 是需要被持久化保存的类。我们需要用 @Entity 注解来标注它,属性通常 private 修饰,然后会自动生成 gettersetter

    ID

    在 ObjectBox 中,每一个 Entity 都需要有 long 类型的 ID 属性,我们需要使用 @Id 来标注它。

    @Entity
    public classUser{
    
        @Id
        private long id;
    
        ...
    }
    

    ID 有以下需要注意的点:

    • 0 代表对象还没被持久化,一个新的需要被持久化的对象的 Id 应为 0
    • 如果需要使用服务器端已经存在的 Id,需要这样标记 @Id(assignable = true) ,这样就不会检查插入对象时对象的 Id

    属性

    通常我们不需要在属性上使用注解,除非:

    • 需要指定特殊的存储在数据库中时的名称,使用 @Property 注解
    • 不需要持久化该属性,使用 @Transient 注解
    @Entity
    public classUser{
    
        @Property(nameInDb = "USERNAME")
        private String name;
    
        @Transient
        private int tempUsageCount;
    
        ...
    }
    

    索引

    使用 @Index 注解可以生成索引,加快查询速度。

    @Entity
    public classUser{
    
        @Id
        private Long id;
    
        @Index
        private String name;
    }
    

    关联

    使用 @Relation 注解可以标注关联关系。

    一对一

    customId 属性会自动生成。

    @Entity
    public classOrder{
        @Id long id;
    
        long customerId;
    
        @Relation
        Customer customer;
    }
    
    @Entity
    public classCustomer{
        @Id long id;
    }
    

    一对多

    一对多的时候,只能修饰 List。

    @Entity
    public classCustomer{
        @Id long id;
    
        // References the ID property in the *Order* entity
        @Relation(idProperty = "customerId")
        List<Order> orders;
    }
    
    @Entity
    public classOrder{
        @Id long id;
    
        long customerId;
    
        @Relation Customer customer;
    }
    

    Query

    首先要获取 Box 对象,然后通过 QueryBuilder 查询,以下是一个找出 firstName 是 Joe 的例子:

    Box<User> userBox = boxStore.boxFor(User.class);
    List<User> joes = userBox.query().equal(User_.firstName, "Joe").build().find();
    

    QueryBuilder 还提供了形如 greaterstartsWith 等 API,使用非常方便。

    分页

    Query<User> query = userBox.query().equal(UserProperties.FirstName, "Joe").build();
    List<User> joes = query.find(10 /** offset by 10 */, 5 /** limit to 5 results */);
    
    • offset : 查询的第一项的 offset
    • limit : 查询多少项

    查询的结果可以直接修改和删除,会同步数据库更改结果。

    Insert

    Box 对象的 put 方法可以插入对象,通常主键的值是 0,如果服务器已经确定主键了需要添加注解标注。

    性能对比

    笔者简单测试了一下和 Realm 对比的性能差距,以 2000 个简单对象为例:

    Insert

    生成 2000 个对象一次性插入数据库

    • objectbox:39ms
    • realm:127ms

    Query

    查询所有 2000 条数据

    • objectbox:22ms
    • realm:40ms

    Delete

    删除所有 2000 条数据

    • objectbox:20ms
    • realm:47ms

    PS: 陷阱,使用ObjectBox时,不应该再在以下地方添加ndk配置,否则的话可能会出现 cannot find libobjectbox.so的错误。

    android{
           ...
               defaultConfig{
                      ndk{ ...  }    //此处应该注释掉,不然会报错找不到 **libobjectbox.so**
              }
           ...
    }
    

    相关文章

      网友评论

        本文标题:Java - Android GreenRobot新作:Obje

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