Android ObjectBox開源數據庫框架學習筆記

目錄

一、前言

二、簡介

​三、實現步驟

(1)項目引用ObjectBox

(2)建立實體類

(3)開始使用

四、額外擴展

(1)使用ObjectBox幫助類來配置BoxStore

(2)註釋說明

(3)查詢

(4)Data Observers & Rx

五、練習項目 

六、Demo地址

七、內容推薦


一、前言

之前一直在使用GreenDao框架,也感覺很是方便。前段時間又翻了一次官網,突然有了一個意外收穫——ObjectBox。GreenDao官網介紹中最前面有這麼一句:

Note: for new apps we recommend ObjectBox, a new object-oriented database that is much faster than SQLite and easier to use.

對於新的應用程序,我們建議使用ObjectBox,這是一個新的面向對象的數據庫,它比SQLite更快更方便使用。

顯然是在極力推薦使用ObjectBox。所以花了點時間學習了一下,還不知道的同學們可一一起來了解..這一篇教你如何使用。當然官網也寫的很詳細,這裏作者簡單的做一個總結。

二、簡介

文檔:https://docs.objectbox.io/

Github:https://github.com/objectbox/objectbox-java

官網對ObjectBox的介紹:

ObjectBox is a super fast database and sychronization solution, built uniquely for Mobile and IoT devices. We bring edge computing to small devices, allowing data to be stored and processed from sensor to server for reliable, fast and secure data management. ObjectBox is smaller than 1MB, so it is the ideal solution across hardware from Mobile Apps, to IoT Devices and IoT Gateways. We are the first high-performance NoSQL, ACID-compliant on-device edge database. All of our products are built with developers in mind, so they are easy to use and take minimal code to implement.

個人勉強可以看懂英文這裏就不獻醜,只好把原文搬過來。https://objectbox.io/  想要了解更多官網走一波。

總結起來就是:速度快 佔用小 使用方便 .... 感覺這就夠了 。不正是我們所需要的那樣麼

好了,廢話就不多說了 。作者向您丟了一坨代碼、、、

​三、實現步驟

(1)項目引用ObjectBox

根目錄build.gradle

buildscript {
    ext.objectboxVersion = '2.3.4'
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.2'
        classpath "io.objectbox:objectbox-gradle-plugin:$objectboxVersion"
    }
}

App build.gradle

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

(2)建立實體類

// User.java
@Entity
public class User {
    //實體必須具有一個類型的long 類型的Id屬性   如若需要使用其它類型的Id  請查看文檔 
    @Id public long id;
    public String name;
}

建立後 :Build> Make project

這會觸發ObjectBox生成一些類,比如ObjectBox內部使用的一些類。 MyObjectBox.java

注意:如果您對實體進行了重大更改,例如通過移動它們或修改註釋,請確保重建項目,以便更新生成的ObjectBox代碼。

核心類:

  • MyObjectBox:基於實體類生成,MyObjectBox提供了一個構建器,用於爲您的應用程序設置BoxStore。
  • BoxStore:入口點使用ObjectBox。BoxStore是您與數據庫的直接接口並管理Boxes。
  • Box:一個Box保存並查詢實體。對於每個實體,都有一個Box(由BoxStore提供)

(3)開始使用

步驟1:獲取BoxStore 

BoxStore boxStore = MyObjectBox.builder().androidContext(context.getApplicationContext()).build();

步驟2:通過BoxStore ,獲取Box

Box<User> userBox = boxStore.boxFor(User.class);

步驟3:通過Box提供的方法對數據進行增刪改查操作

//Box常用函數 更多請查看API文檔
count():返回Box中存儲對象的數量
get​():獲取存儲對象
getAll():獲取所有存儲對象
isEmpty():判斷Box中是否有對象
put​():存儲與更新對象 
query():查詢數據
remove​():刪除指定數據
removeAll():刪除所有數據

四、額外擴展

(1)使用ObjectBox幫助類來配置BoxStore

/**
* 在Application類onCreate()方法中調用:ObjectBox.init(this);
* 可以在ObjectBox幫助類中初始化BoxStore
*/
public class ObjectBox {
    private static BoxStore boxStore;

    public static void init(Context context) {
        boxStore = MyObjectBox.builder()
                .androidContext(context.getApplicationContext())
                .build();
    }

    public static BoxStore get() { return boxStore; }
}
Box<User> userBox = ObjectBox.get().boxFor(User.class);

(2)註釋說明

  • @Entity:ObjectBox只保存用此註釋標記的類的對象
  • @Id:實體必須有一個long類型的Id屬性,這樣能有效的獲取或引用對象
  • @NameInDb:如果名稱在Java端出現分歧(相對於DB),可以在這裏指定數據庫中使用的名稱。允許在Java中進行簡單的重命名。
  • @Transient:表示該字段不會持久存儲在數據庫中
  • @Index:指定該屬性爲索引,如果使用該屬性進行查詢。查詢該屬性時,可以提高性能。
  • @Unique:將屬性值標記爲唯一
  • @Backlink:定義反向鏈接關係,該關係基於另一個反向關係
  • @BaseEntity:實體基類的註釋。
  • @NotNull:指定該屬性不爲空
  • @TargetIdProperty:定義作爲ToOne的目標ID的屬性。

(3)查詢

官網摘錄:

1.查詢名 Joe的所有用戶

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

2.多個條件示例:獲取名字爲“Joe”的用戶,這些用戶出生晚於1970年,其姓氏以“O”開頭。

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

 

3.排序

userBox.query().equal(User_.firstName, "Joe")
.order(User_.lastName, QueryBuilder.DESCENDING | QueryBuilder.CASE_SENSITIVE)
.find();

4.限制,偏移和分頁

 

Query<User> query = userBox.query().equal(UserProperties.FirstName, "Joe").build();
List<User> joes = query.find(/* offset by */ 10, /* limit to */ 5 /* results */);

 

5.如果您只想返回某個屬性的值而不是完整對象列表,則可以使用PropertyQuery

String[] emails = userBox.query().build().property(User_.email).findStrings();

6.處理空值:默認情況下,不返回空值。但是,如果屬性爲null,則可以指定要返回的替換值

 

 

String[] emails = userBox.query().build()
.property(User_.email)
.nullValue("unknown")
.findStrings();

7.返回值去重

String[] names = userBox.query().build()
.property(User_.firstName)
.distinct()
.findStrings();

 

8.默認情況下,將忽略字符串的大小寫。但是,可以重載distinct調用以啓用區分大小寫:

String[] names = userBox.query().build()
.property(User_.firstName)
.distinct(StringOrder.CASE_SENSITIVE)
.findStrings();

9.聚合值

min()/ :在與查詢匹配的所有對象上查找給定屬性的最小值。minDouble()
max()/ :找到最大值。maxDouble()
sum()/ :計算所有值的總和。注意:非double版本檢測溢出並在這種情況下拋出異常。sumDouble()
avg() :計算所有值的平均值(總是兩倍)。
count():返回結果數。這比查找和獲取結果數組的長度更快。可以結合使用,僅計算不同值的數量。自2.0.0起distinct()

10.查詢過濾器

 

// Reduce object count to reasonable value
songBox.query().equal(Song_.bandId, bandId)
// Filter is performed on candidate objects
.filter((song) -> {
return song.starCount * 2 > song.downloads;
})

(4)Data Observers & Rx

簡單理解:ObjectBox提供了Observer關聯,可以使數據庫操作在子線程進行,在主線程中及時進行UI更新。

具體可以查看官網 ,下面是個人寫的一個Demo。大家可以參考參考

import java.util.List;
import io.objectbox.Box;
import io.objectbox.android.AndroidScheduler;
import io.objectbox.query.Query;
import io.objectbox.reactive.DataObserver;
import io.objectbox.reactive.DataSubscriptionList;
import io.objectbox.reactive.DataTransformer;
import io.objectbox.reactive.ErrorObserver;
/**
 * ObjectBox
 */
public class LinQuery<T> {

    private DataSubscriptionList subscriptions = new DataSubscriptionList();

    public Box getBox(Class<T> object){
        Box<T> tBox = ObjectBox.get().boxFor(object);
        return tBox;
    }

    public void subscribes(Query<T> query,DataTransformer datas,ErrorObserver error,DataObserver success) {
        query.subscribe(subscriptions).on(AndroidScheduler.mainThread()).transform(datas).onError(error).observer(success);
    }

    /**
     * 取消訂閱
     */
    public void cancelSubscribe() {
        subscriptions.cancel();
    }

    /**
     * 轉換數據
     */
    DataTransformer datas = new DataTransformer<List<T>, Object>() {
        @Override
        public Object transform(List<T> source) throws Exception {
            return null;
        }
    };
    /**
     * 錯誤返回
     */
    ErrorObserver error =  new ErrorObserver() {
        @Override
        public void onError(Throwable th) {

        }
    };
    /**
     * 成功返回
     */
    DataObserver success = new DataObserver<T>() {
        @Override
        public void onData(T data) {

        }
    };
}

五、練習項目 

實踐是檢驗真理的唯一標準

  

學習了之後,當然要練習一下,如果跟看書似的的過一遍又會很快忘記。所以寫了個Demo,加深印象還是很有必要的。

效果預覽:

           

          

主要是根據一對一、一對多、多對多等關係來進行數據庫的一些簡單操作。

這裏簡單的貼部分單一存儲操作代碼、想了解更多的可以去項目裏面查看

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_add://增
                User user1 = new User();
                user1.setName("xx" + i++);
                userBox.put(user1);
                query();
                break;
            case R.id.btn_delete://刪
                List<User> users1 = userBox.query().build().find();
                int v2 = (int)(Math.random() * (users1.size()));
                userBox.remove( users1.get(v2));
                query();
                break;
            case R.id.btn_update://改
                List<User> users = userBox.query().build().find();
                if(users.size()==0) return;
                int v1 = (int)(Math.random() * (users.size()));
                User user = users.get(v1);
                if(user.getName().contains("xx")){
                    user.setName("oo"+v1);
                }else{
                    user.setName("xx"+v1);
                }
                userBox.put(user);
                query();
                break;
            case R.id.btn_query://查
                query();
                break;
        }
    }
    private void query() {
        List<User> all = userBox.getAll();
        adapter.setData(all);
    }

這裏沒有用訂閱、作者比較懶就沒寫了。 如果在項目中可以考慮查詢的時候用observer。

六、Demo地址

Github:https://github.com/DayorNight/ObjectBoxDemo

七、內容推薦

簡書:

《Android 仿RxDialog自定義DialogFragment》

《Android 獲取App應用、緩存、數據等大小適配8.0(仿微信存儲空間)》

《Android 仿微信多語言切換》

《Android 仿微信全局字體大小調整》

《Android Rxjava+Retrofit網絡請求框架封裝(一)》

如果你覺得寫的不錯或者對您有所幫助的話

不妨頂一個【微笑】,別忘了點贊、收藏、加關注哈

看在花了這麼多時間整理寫成文章分享給大家的份上,記得手下留情哈

您的每個舉動都是對我莫大的支持

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章