美文网首页开源库
Android ObjectBox

Android ObjectBox

作者: 全球顶尖伪极客 | 来源:发表于2019-04-02 11:02 被阅读0次

Github地址:objectbox/objectbox-java
官网objectbox参考文档

Gradle setup

Add this to your root build.gradle (project level):

buildscript {
    ext.objectboxVersion = '2.3.4'
    respositories {
        jcenter()
    }
    dependencies {
        // Android Gradle Plugin 3.0.0 or later supported
        classpath 'com.android.tools.build:gradle:3.3.2'
        classpath "io.objectbox:objectbox-gradle-plugin:$objectboxVersion"
    }
}

And this to our app's build.gradle (module level):

apply plugin: 'com.android.application'
apply plugin: 'io.objectbox' // apply last

Data Browser

The ObjectBox data browser (object browser) allows you to view the entities and schema of your database inside a regular web browser, and download entities in JSON format.
Setup We strongly recommend to use the object browser only for debug builds.

dependencies {
    debugImplementation "io.objectbox:objectbox-android-objectbrowser:$objectboxVersion"
    releaseImplementation "io.objectbox:objectbox-android:$objectboxVersion"
}

// apply the plugin after the dependencies block 放到android{}外层,也就是最后,不然会报错,冲突
apply plugin: 'io.objectbox'
Duplicate class io.objectbox.android.AndroidObjectBrowser found in modules classes.jar (io.objectbox:objectbox-android-objectbrowser:2.3.4) and classes.jar (io.objectbox:objectbox-android:2.3.4)
Duplicate class io.objectbox.android.AndroidObjectBrowserReceiver found in modules classes.jar (io.objectbox:objectbox-android-objectbrowser:2.3.4) and classes.jar (io.objectbox:objectbox-android:2.3.4)
Duplicate class io.objectbox.android.AndroidObjectBrowserService found in modules classes.jar (io.objectbox:objectbox-android-objectbrowser:2.3.4) and classes.jar (io.objectbox:objectbox-android:2.3.4)
Duplicate class io.objectbox.android.AndroidScheduler found in modules classes.jar (io.objectbox:objectbox-android-objectbrowser:2.3.4) and classes.jar (io.objectbox:objectbox-android:2.3.4)
Duplicate class io.objectbox.android.AndroidScheduler$Runner found in modules classes.jar (io.objectbox:objectbox-android-objectbrowser:2.3.4) and classes.jar (io.objectbox:objectbox-android:2.3.4)
Duplicate class io.objectbox.android.BuildConfig found in modules classes.jar (io.objectbox:objectbox-android-objectbrowser:2.3.4) and classes.jar (io.objectbox:objectbox-android:2.3.4)
Duplicate class io.objectbox.android.ObjectBoxDataSource found in modules classes.jar (io.objectbox:objectbox-android-objectbrowser:2.3.4) and classes.jar (io.objectbox:objectbox-android:2.3.4)
Duplicate class io.objectbox.android.ObjectBoxDataSource$1 found in modules classes.jar (io.objectbox:objectbox-android-objectbrowser:2.3.4) and classes.jar (io.objectbox:objectbox-android:2.3.4)
Duplicate class io.objectbox.android.ObjectBoxDataSource$Factory found in modules classes.jar (io.objectbox:objectbox-android-objectbrowser:2.3.4) and classes.jar (io.objectbox:objectbox-android:2.3.4)
Duplicate class io.objectbox.android.ObjectBoxLiveData found in modules classes.jar (io.objectbox:objectbox-android-objectbrowser:2.3.4) and classes.jar (io.objectbox:objectbox-android:2.3.4)
Duplicate class io.objectbox.android.ObjectBoxLiveData$1 found in modules classes.jar (io.objectbox:objectbox-android-objectbrowser:2.3.4) and classes.jar (io.objectbox:objectbox-android:2.3.4)

Go to the documentation to learn how to Fix dependency resolution errors.

  • I/ObjectBrowser: ObjectBrowser started: http://localhost:8090
  • I/ObjectBrowser: Command to forward ObjectBrowser to connected host:adb forward tcp:8090 tcp:8090

创建entity,必带@Entity@Id注解,并Make Project

  • @Entity这个对象需要持久化(加在bean/entity类的最上方)
  • @Id 这个对象的主键(会自增长,按照一定格式,下面的实例会给出)
  • @Index 这个对象中的索引(对经常大量进行查询的字段创建索引,会提高你的查询性能、除了查询别的慢)
  • @NameInDb 有的时候数据库中的字段跟你的对象字段不匹配的时候,可以使用此注解
  • @Transient 如果你有某个字段不想被持久化,可以使用此注解
  • @Relation 做一对多ToOne<>,多对一ToMany<>的注解

Make entity data accessible

ObjectBox needs to access the data of your entity’s properties (e.g. in generated Cursor classes). You have two options

    1. Give your property fields at least “package private” (not “private”) visibility. In Kotlin, you can use @JvmField.
    1. Provide standard getters (your IDE can generate them easily).`
/**
 * created by cheng.qx on 2019/4/3 19:05
 * The @Entity annotation identifies the Java class User as a persistable entity.
 * This will trigger ObjectBox to generate persistence code tailored for this class.
 */
@Entity
public class User {
    /**
     * In ObjectBox, entities must have one @Id property of type long  to efficiently get or reference objects.
     * You can use the nullable type java.lang.Long, but we do not recommend it.
     */
    @Id
    private long id;
    @Unique
    private long userId;
    /**
     * @NameInDb lets you define a name on the database level for a property.
     * This allows you to rename the Java field without affecting the property name on the database level.
     */
    @NameInDb("Name")
    private String name;
    private String age;
    @Transient
    private String address;// not persisted
.....getters and setters for properties...

增删改查

  • .put(),参数可以是集合、也可以是单个对象,单个对象时该Api返回放入数据库后的对象id
public class MainActivity extends AppCompatActivity {
    private BoxStore mBoxStore;
    private Box<User> mUserBox;
    private Box<Student> mStudentBox;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBoxStore =ObjectBox.get();
        mUserBox = ObjectBox.get().boxFor(User.class);
        mStudentBox = mBoxStore.boxFor(Student.class);
        for (int i = 0; i <10 ; i++) {
            User user=new User();
            user.setAddress("省市区");
            user.setName("哈哈哈"+i);
            mUserBox.put(user);
        }
    }

}
  • .remove()系列Api,参数可以是对象、对象集合、对象id、对象id集合等,你还可以直接使用removeAll()来清空某个对象的数据库。不同于一些数据库会返回被删除对象,ObjectBox的删除操作均返回void
 query.remove(user);
        user.setName("This name has changed.");
        mUserBox.put(user);
  • :使用.query()获取一个QueryBuilder,使用builder.equal()进行设置匹配。该步可以调用startWith()等Api进行精确设置。之后进行build()获取一个Query对象,然后就可以执行各种花式操作了。下面是Query的一些Api。关于整个查询可以参照官方详细查询操作
    注意,查询中设置属性应该使用生成类的属性。比如User生成类User_,要使用到年龄属性可以使用User_.age()

QueryBuilder offers several methods to define query conditions for properties of an entity. To specify a property ObjectBox does not use Strings but meta information"underscore" classes (like User_) that are generated during build time. The meta information classes have a static field for each property (like User_.firstName)。

List<User> hah= mUserBox.query().equal(User_.Name, "哈哈哈1").build().find();
QueryBuilder<User> builder = userBox.query();
builder.equal(User_.firstName, "Joe")
        .greater(User_.yearOfBirth, 1970)
        .startsWith(User_.lastName, "O");
List<User> youngJoes = builder.build().find();

userBox.query().equal(User_.firstName, "Joe")
    .order(User_.lastName, QueryBuilder.DESCENDING | QueryBuilder.CASE_SENSITIVE)
    .find();
  • 查找find()、findfirst()、findUnique()。如名字,最后一个是从匹配结果里找出一个独特的唯一,没有或者有多个都返回nullQuery<User> query=mUserBox.query().order(User_.name).build();

  • 精确查找设置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()。

  • count:统计Returns the number of objects stored in this box

The best time to initialize ObjectBox is when your app starts. We suggest to do it in the onCreate method of your Application class

/**
 * created by cc.qx on 2019/4/3 20:47
 */
public class App extends Application {
    private static BoxStore mBoxStore;

    @Override
    public void onCreate() {
        super.onCreate();
        ObjectBox.init(this);
        mBoxStore=ObjectBox.get();
    }
    public static BoxStore getBoxStore(){
        return mBoxStore;
    }
}


Rxjava下的ObjectBox

/**
 * Static methods to Rx-ify ObjectBox queries.
 */
public abstract class RxBoxStore {
 private static final String TAG = "ObjectBox";

    //ObjectBox数据库
    private static BoxStore boxStore;

    /**
     * 初始化ObjectBox
     * @param context
     */
    public static void init(Context context){
        //初始化ObjectBox数据库
        boxStore = MyObjectBox.builder().androidContext(context.getApplicationContext()).build();
        //DEBUG模式下开启ObjectBox数据调试
        if (BuildConfig.DEBUG) {
            boolean started = new AndroidObjectBrowser(boxStore).start(context.getApplicationContext());
            Log.d(TAG, "ObjectBox Debug Started: " + started);
        }
    }

    /**
     * 返回BoxStore对象
     * @return
     */
    public static BoxStore getBoxStore(){

        return boxStore;
    }

    /**
     * Using the returned Observable, you can be notified about data changes.
     * Once a transaction is committed, you will get info on classes with changed Objects.
     */
    public static <T> Observable<Class> observable(final BoxStore boxStore) {
        return Observable.create(new ObservableOnSubscribe<Class>() {
            @Override
            public void subscribe(final ObservableEmitter<Class> emitter) throws Exception {
                final DataSubscription dataSubscription = boxStore.subscribe().observer(new DataObserver<Class>() {
                    @Override
                    public void onData(Class data) {
                        if (!emitter.isDisposed()) {
                            emitter.onNext(data);
                        }
                    }
                });
                emitter.setCancellable(new Cancellable() {
                    @Override
                    public void cancel() throws Exception {
                        dataSubscription.cancel();
                    }
                });
            }
        });
    }

}
/**
 * Static methods to Rx-ify ObjectBox queries.
 */
public abstract class RxQuery {
    /**
     * The returned Flowable emits Query results one by one. Once all results have been processed, onComplete is called.
     * Uses BackpressureStrategy.BUFFER.
     */
    public static <T> Flowable<T> flowableOneByOne(final Query<T> query) {
        return flowableOneByOne(query, BackpressureStrategy.BUFFER);
    }

    /**
     * The returned Flowable emits Query results one by one. Once all results have been processed, onComplete is called.
     * Uses given BackpressureStrategy.
     */
    public static <T> Flowable<T> flowableOneByOne(final Query<T> query, BackpressureStrategy strategy) {
        return Flowable.create(new FlowableOnSubscribe<T>() {
            @Override
            public void subscribe(final FlowableEmitter<T> emitter) throws Exception {
                createListItemEmitter(query, emitter);
            }

        }, strategy);
    }

    static <T> void createListItemEmitter(final Query<T> query, final FlowableEmitter<T> emitter) {
        final DataSubscription dataSubscription = query.subscribe().observer(new DataObserver<List<T>>() {
            @Override
            public void onData(List<T> data) {
                for (T datum : data) {
                    if (emitter.isCancelled()) {
                        return;
                    } else {
                        emitter.onNext(datum);
                    }
                }
                if (!emitter.isCancelled()) {
                    emitter.onComplete();
                }
            }
        });
        emitter.setCancellable(new Cancellable() {
            @Override
            public void cancel() throws Exception {
                dataSubscription.cancel();
            }
        });
    }

    /**
     * The returned Observable emits Query results as Lists.
     * Never completes, so you will get updates when underlying data changes.
     */
    public static <T> Observable<List<T>> observable(final Query<T> query) {
        return Observable.create(new ObservableOnSubscribe<List<T>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<T>> emitter) throws Exception {
                final DataSubscription dataSubscription = query.subscribe().observer(new DataObserver<List<T>>() {
                    @Override
                    public void onData(List<T> data) {
                        if (!emitter.isDisposed()) {
                            emitter.onNext(data);
                        }
                    }
                });
                emitter.setCancellable(new Cancellable() {
                    @Override
                    public void cancel() throws Exception {
                        dataSubscription.cancel();
                    }
                });
            }
        });
    }

    /**
     * The returned Single emits one Query result as a List.
     */
    public static <T> Single<List<T>> single(final Query<T> query) {
        return Single.create(new SingleOnSubscribe<List<T>>() {
            @Override
            public void subscribe(final SingleEmitter<List<T>> emitter) throws Exception {
                query.subscribe().single().observer(new DataObserver<List<T>>() {
                    @Override
                    public void onData(List<T> data) {
                        if (!emitter.isDisposed()) {
                            emitter.onSuccess(data);
                        }
                    }
                });
                // no need to cancel, single never subscribes
            }
        });
    }
}

相关文章

网友评论

    本文标题:Android ObjectBox

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