目錄
一、前言
二、簡介
?三、實現(xiàn)步驟
(1)項目引用
(2)建立實體類
(3)開始使用
四、額外擴(kuò)展
(1)使用ObjectBox幫助類來配置BoxStore
(2)注釋說明
(3)查詢
(4)Data Observers & Rx
五、練習(xí)項目
六、Demo地址
七、內(nèi)容推薦
一、前言
之前一直在使用GreenDao框架,也感覺很是方便。前段時間又翻了一次官網(wǎng),突然有了一個意外收獲——ObjectBox。GreenDao官網(wǎng)介紹中最前面有這么一句:
Note: for new apps we recommend ObjectBox, a new object-oriented database that is much faster than SQLite and easier to use.
對于新的應(yīng)用程序,我們建議使用ObjectBox,這是一個新的面向?qū)ο蟮臄?shù)據(jù)庫,它比SQLite更快更方便使用。
顯然是在極力推薦使用ObjectBox。所以花了點時間學(xué)習(xí)了一下,還不知道的同學(xué)們可一一起來了解..這一篇教你如何使用。當(dāng)然官網(wǎng)也寫的很詳細(xì),這里作者簡單的做一個總結(jié)。

二、簡介
Github:https://github.com/objectbox/objectbox-java
官網(wǎng)對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.
個人勉強(qiáng)可以看懂英文這里就不獻(xiàn)丑,只好把原文搬過來。https://objectbox.io/ 想要了解更多官網(wǎng)走一波。
總結(jié)起來就是:速度快 占用小 使用方便 .... 感覺這就夠了 。不正是我們所需要的那樣么
好了,廢話就不多說了 。作者向您丟了一坨代碼、、、

?三、實現(xiàn)步驟
(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
這會觸發(fā)ObjectBox生成一些類,比如ObjectBox內(nèi)部使用的一些類。 MyObjectBox.java
注意:如果您對實體進(jìn)行了重大更改,例如通過移動它們或修改注釋,請確保重建項目,以便更新生成的ObjectBox代碼。
核心類:
- MyObjectBox:基于實體類生成,MyObjectBox提供了一個構(gòu)建器,用于為您的應(yīng)用程序設(shè)置BoxStore。
- BoxStore:入口點使用ObjectBox。BoxStore是您與數(shù)據(jù)庫的直接接口并管理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提供的方法對數(shù)據(jù)進(jìn)行增刪改查操作
//Box常用函數(shù) 更多請查看API文檔
count():返回Box中存儲對象的數(shù)量
get?():獲取存儲對象
getAll():獲取所有存儲對象
isEmpty():判斷Box中是否有對象
put?():存儲與更新對象
query():查詢數(shù)據(jù)
remove?():刪除指定數(shù)據(jù)
removeAll():刪除所有數(shù)據(jù)
四、額外擴(kuò)展
(1)使用ObjectBox幫助類來配置BoxStore
/**
* 在Application類onCreate()方法中調(diào)用: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只保存用此注釋標(biāo)記的類的對象
- @Id:實體必須有一個long類型的Id屬性,這樣能有效的獲取或引用對象
- @NameInDb:如果名稱在Java端出現(xiàn)分歧(相對于DB),可以在這里指定數(shù)據(jù)庫中使用的名稱。允許在Java中進(jìn)行簡單的重命名。
- @Transient:表示該字段不會持久存儲在數(shù)據(jù)庫中
- @Index:指定該屬性為索引,如果使用該屬性進(jìn)行查詢。查詢該屬性時,可以提高性能。
- @Unique:將屬性值標(biāo)記為唯一
- @Backlink:定義反向鏈接關(guān)系,該關(guān)系基于另一個反向關(guān)系
- @BaseEntity:實體基類的注釋。
- @NotNull:指定該屬性不為空
- @TargetIdProperty:定義作為ToOne的目標(biāo)ID的屬性。
(3)查詢
官網(wǎng)摘錄:
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.處理空值:默認(rèn)情況下,不返回空值。但是,如果屬性為null,則可以指定要返回的替換值
String[] emails = userBox.query().build()
.property(User_.email)
.nullValue("unknown")
.findStrings();
7.返回值去重
String[] names = userBox.query().build()
.property(User_.firstName)
.distinct()
.findStrings();
8.默認(rèn)情況下,將忽略字符串的大小寫。但是,可以重載distinct調(diào)用以啟用區(qū)分大小寫:
String[] names = userBox.query().build()
.property(User_.firstName)
.distinct(StringOrder.CASE_SENSITIVE)
.findStrings();
9.聚合值
min()/ :在與查詢匹配的所有對象上查找給定屬性的最小值。minDouble()
max()/ :找到最大值。maxDouble()
sum()/ :計算所有值的總和。注意:非double版本檢測溢出并在這種情況下拋出異常。sumDouble()
avg() :計算所有值的平均值(總是兩倍)。
count():返回結(jié)果數(shù)。這比查找和獲取結(jié)果數(shù)組的長度更快??梢越Y(jié)合使用,僅計算不同值的數(shù)量。自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關(guān)聯(lián),可以使數(shù)據(jù)庫操作在子線程進(jìn)行,在主線程中及時進(jìn)行UI更新。
具體可以查看官網(wǎng) ,下面是個人寫的一個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();
}
/**
* 轉(zhuǎn)換數(shù)據(jù)
*/
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) {
}
};
}
五、練習(xí)項目
實踐是檢驗真理的唯一標(biāo)準(zhǔn)

學(xué)習(xí)了之后,當(dāng)然要練習(xí)一下,如果跟看書似的的過一遍又會很快忘記。所以寫了個Demo,加深印象還是很有必要的。
效果預(yù)覽:
主要是根據(jù)一對一、一對多、多對多等關(guān)系來進(jìn)行數(shù)據(jù)庫的一些簡單操作。
這里簡單的貼部分單一存儲操作代碼、想了解更多的可以去項目里面查看
@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
七、內(nèi)容推薦
CSDN:
《Android 仿RxDialog自定義DialogFragment》
如果你覺得寫的不錯或者對您有所幫助的話
不妨頂一個【微笑】,別忘了點贊、收藏、加關(guān)注哈
看在花了這么多時間整理寫成文章分享給大家的份上,記得手下留情哈
您的每個舉動都是對我莫大的支持
