## 1.UnifyStorage说明
此库主要用来解决下面几个问题:
**1).存储对象以及对象集合数据到本地数据库
2).存储基本数据类型的数据或者对象,对象集合类型的数据为key-value形式(可类比sharepreference)
3).网络中下载的大json解析到内存会出现内存爆炸,这里提供直接json到数据库的存储的一种选择
4).mock网络访问直接返回本地的json对应的对象或者对象集合(目前提供retrofit网络访问的mock方式,之后这部分会集成到framework)**
> 同时此库提供统一的维护点和相同的对外方式,减少了业务系统后期的维护成本和扩展成本。
[TOC]
## 2.集成
UnifyStorage综合考虑各种移动端数据库性能以及可干预程度,最终采用realm作为存储数据库,但是这部分是对用户无感知的。更多一些知识可以参看下面文档:
数据库性能对比分析可以点击此网页进行查看:
[https://www.aliyun.com/jiaocheng/1354383.html](https://www.aliyun.com/jiaocheng/1354383.html)
如果想了解更多关于realm的知识可以查看我们上一篇文章:https://www.kancloud.cn/sharkchao/sharkchao/858754
官方关于realm的技术文档:https://realm.io/docs/java/latest/
### 2.1集成说明
> JDK version 7.0 及以上
> Android API 9 以上 (Android 2.3及以上)
#### 1)添加项目依赖(目前还未上传至仓库)
1.在app目录下的build.gradle添加如下项目依赖
```
implementation project(':unifystorage_core')//存储库
implementation project(':unifystorage_mock')//mock网络访问的库
```
同时需要在此build.gradle里面添加插件:
```
apply plugin: 'realm-android'
```
2.在项目目录下的build.gradle添加如下:
```
classpath "io.realm:realm-gradle-plugin:5.8.0"
```
这个是realm数据库的要求。
#### 2)在application中的onCreate()方法中进行初始化
```
UStorage.initialize(this);
```
#### 3)定义需要进行的操作,这个地方以数据库查询为例
```
public interface ApiDataBase {
@DB(table = User.class)
@FIND(where = "name = ? and (age > ? or sex = ?)",limit = 10,orderBy = "age")
DbResult<User> findUser(String name, int age, String sex);
}
```
> 完整的使用类如下:
> public interface ApiDataBase {
>
> @DB(table = User.class)
> @SAVE
> DbResult saveUser(User user);
>
> @DB(table = User.class)
> @SAVE(type = Constants.JSON_OBJECT)
> DbResult saveUsersByJsonObject(String jsonObject);
>
> @DB(table = User.class)
> @SAVE(type = Constants.JSON_ARRAY)
> DbResult saveUsersByJsonArray(String jsonArray);
>
> @DB(table = User.class)
> @SAVEORUPDATE(type = Constants.JSON_ARRAY)
> DbResult saveOrUpdateUsersByJsonArray(String jsonArray);
>
> @DB(table = User.class)
> @SAVEORUPDATE(type = Constants.JSON_OBJECT)
> DbResult saveOrUpdateUsersByJsonObject(String jsonObject);
>
> @DB(table = User.class)
> @SAVE
> DbResult saveUsersByList(List<User> user);
>
> @DB(table = User.class)
> @SAVE
> DbResult saveUsersByArray(User[] user);
>
> @DB(table = User.class)
> @SAVE
> DbResult saveFake(Fake fake);
>
>
> @DB(table = User.class)
> @SAVEORUPDATE
> DbResult saveOrUpdateUser(User user);
>
> @DB(table = User.class)
> @SAVEORUPDATE
> DbResult saveOrUpdateUsersByList(List<User> user);
>
> @DB(table = User.class)
> @SAVEORUPDATE
> DbResult saveOrUpdateUsersByArray(User[] user);
>
> @DB(table = User.class)
> @FIND
> DbResult<User> findAll();
>
> @DB(table = User.class)
> @FIND(where = "name = ? and (age > ? or sex = ?)",limit = 10,orderBy = "age desc")
> DbResult<User> findUser(String name, int age, String sex);
>
> @DB(table = User.class)
> @FIND(where = "name in ?",limit = 10)
> DbResult<User> findUsers(List<String> users);
>
> @DB(table = User.class)
> @DELETE(where = "name = ?")
> DbResult deleteUsersByQuery();
>
> @DB(table = User.class)
> @FIND(where = "name in ?")
> DbResult<User> findUserByIn(List<String> users);
>
> @DB(table = User.class)
> @FIND(where = "name contains ?",distinct = "name")
> DbResult<User> findUserByContains(String name);
>
> @DB(table = User.class)
> @FIND(where = "name like ? and age > ?",distinct = "name")
> DbResult<User> findUserByLike(String name, int age);
>
> @DB(table = User.class)
> @FIND(where = "? notnull",limit = 2)
> DbResult<User> findUserByNotNull(String name);
>
> @DB(table = User.class)
> @UPDATE(where = "name = ?",set = "name = ? and age = ?")
> DbResult updateUsersByQuery(String oldName,String newName,String age);
>
>
> @JSON(key = "JSON_KEY",convert = User.class)
> boolean saveJson(User user);
>
> @JSON(key = "JSON_ARRAY",convert = User.class)
> boolean saveJsonArray(List<User> users);
>
> @JSON(key = "JSON_STR")
> boolean saveStr(String str);
>
> @JSON(key = "JSON_INT")
> boolean saveInt(int ints);
>
> @JSON(key = "JSON_BOOL")
> boolean saveBool(boolean booleans);
>
> @GETJSON(key = "JSON_KEY",convert=User.class)
> DbResult<User> getJson();
>
> @GETJSON(key = "JSON_ARRAY",convert = User[].class)
> DbResult<List<User>> getJsonArray();
>
> @GETJSON(key = "JSON_STR")
> DbResult<String> getStr();
>
> @GETJSON(key="JSON_BOOL",convert = Boolean.class)
> DbResult<Boolean> getBool();
>
> @GETJSON(key = "JSON_INT",convert = Integer.class)
> DbResult<Integer> getInt();
>
> @GET("/getUser")
> Call<User> getUser();
>
> @GET("/getUserList")
> Call<List<User>> getUserList();
> }
#### 4)得到ApiDataBase接口实例
```
public class ApiServiceModule {
private volatile static ApiServiceModule mInstance;
private ApiServiceModule(){
}
public static ApiServiceModule getInstance(){
if (null == mInstance){
synchronized (ApiServiceModule.class){
if (null == mInstance){
mInstance = new ApiServiceModule();
}
}
}
return mInstance;
}
private UStorage provideUStorage(){
return new UStorage.Builder()
.setSchemaVersion(1)
.build();
}
<T> T provideApiService(Class<T> apiDataBase){
return provideUStorage().create(apiDataBase);
}
}
```
#### 5)程序调用
```
mApiDataBase = ApiServiceModule.getInstance().provideApiService(ApiDataBase.class);
mApiDataBase.findUser("sharkchao", 20, "男")
.registerDbFindCallBack(new DbResult.DbFindCallBack<User>() {
@Override
public void onFirstFindResult(RealmResults<User> realmResults) {
UserData.setmResults(realmResults);
Toast.makeText(MainActivity.this, "成功!"+ realmResults.size(), Toast.LENGTH_SHORT).show();
}
@Override
public void onChange(RealmResults<User> realmResults) {
}
});
```
到此数据库的查询操作已经完成。
## 3.UnifyStorage注解
### 3.1 指定数据库表`@DB`
```
eg: @DB(table = User.class)
```
| 注解代码 | 说明 |
| --- | --- |
| @DB | @DB(table = User.class),指定当前接口方法所要操作的数据库表,User.class需继承RealmObject |
### 3.2 存储数据`@SAVE`
```
eg: @SAVE(type = Constants.JSON_OBJECT)
//默认为Constants.REALM_DATA
```
| type属性说明 | 详解|
| --- | --- |
| Constants.JSON_OBJECT|json字符串(单个对象)|
| Constants.JSON_ARRAY | json字符串(多个对象) |
| Constants.REALM_DATA | RealmObject对象,数组,集合|
### 3.3 存储或更新数据`@SAVEORUPDATE`
```
eg: @SAVEORUPDATE(type = Constants.JSON_OBJECT)
//默认为Constants.REALM_DATA
```
| type属性说明 | 详解|
| --- | --- |
| Constants.JSON_OBJECT|json字符串(单个对象)|
| Constants.JSON_ARRAY | json字符串(多个对象) |
| Constants.REALM_DATA | RealmObject对象,数组,集合|
### 3.4 查询数据`@FIND`
```
eg: @FIND(where="name = ?",limit = 10,orderBy = "age",distinct = "name")
```
| 使用代码 | 详解|
| --- | --- |
| where="name = ? and age > ?" | where支持and,or 等组合条件查询 |
| where="name in ?"|where支持查询条件是一个集合 |
| where="name contains ?"|where支持部分字段满足条件查询 |
| where="name like ?"|where支持模糊查询 |
| where="? notnull"|where支持属性不为空查询 |
| limit = 10|限定结果为10条 |
| distinct = "name"|支持指定字段去重查询 |
| orderBy = "age asc"|asc为升序,desc为降序,默认为升序 |
### 3.5 删除数据`@DELETE`
```
eg: @DELETE(where="name = ?",limit = 10,orderBy = "age",distinct = "name")
```
删除数据注解同`@FIND`注解相同。
### 3.6 更新数据`@UPDATE`
@UPDATE只负责更新,不负责插入。如果想要更新数据库还没插入的数据,您注册的DbResult.DbResultCallback会回调onError。
```
eg: @UPDATE(where="name = ?",limit = 10,orderBy = "age",distinct = "name",set="name = ?")
```
更新数据注解除`@FIND`注解相同属性之外,还增加了`set="?"`,为要更新的值。
| set属性说明 | 详解|
| --- | --- |
| set = "name = "?" and age = ?"|可以把指定数据更新为set内的值|
### 3.7 key-value存储/获取 `@JSON @GETJSON`
| set属性说明 | 详解|
| --- | --- |
| @JSON | 用来标识要存储数据到本地文件 |
| @GETJSON | 用来标识要从本地文件中获取数据 |
## 4.存储
使用@SAVE注解,如果数据库中存在此条数据,则您注册的监听DbResult.DbResultCallback会回调onError()。如何注册监听下文会有详解。
UnifyStorage插入数据支持以下几种数据类型:
> 1. 对象(需继承RealmObject)
> 2. List<? extends RealmObject>
> 3. RealmObject[]
> 4. json字符串
### 4.1存储对象
要存储的对象需要继承RealmObject
```
@DB(table = User.class)
@SAVE
DbResult saveUser(User user);
```
### 4.2存储List
要存储的List为List<? extends RealmObject>
```
@DB(table = User.class)
@SAVE
DbResult saveUsersByList(List<User> user);
```
### 4.3存储数组
要存储的数组为RealmObject[]
```
@DB(table = User.class)
@SAVE
DbResult saveUsersByArray(User[] user);
```
### 4.4存储json对象字符串
要存储的数组为json对象字符串
```
@DB(table = User.class)
@SAVE(type = Constants.JSON_OBJECT)
DbResult saveUsersByJsonObject(String jsonObject);
```
### 4.5存储json数组字符串
要存储的数组为json数组字符串
```
@DB(table = User.class)
@SAVE(type = Constants.JSON_ARRAY)
DbResult saveUsersByJsonArray(String jsonArray);
```
## 5.存储或更新
使用@SAVEORUPDATE注解进行插入或更新时,如果数据库中存在此条数据,则会执行更新操作,否则执行插入操作。
具体使用同存储操作类似,详见上文。
## 6.查询数据
查询的时候需要在接口方法上面添加@FIND注解,当然数据库相关的操作都需要@DB注解来注解。
首先我们看下@FIND注解的定义:
```
@Documented
@Target(METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FIND {
String orderBy() default "";
String where() default "";
String distinct() default "";
int limit() default 0;
boolean eager() default true;
}
```
其中where是标识查询条件的,orderBy是标识排序的,默认情况下是升序排序,distinct是标识去重操作的,limit是标识查询出来个数的,eager这个地方暂时未使用。
### 6.1 条件查询
1.首先我们看下查询方法定义:
```
@DB(table = User.class)
@FIND
DbResult<User> findAll();
```
如果什么都不写,那么就是查询所有。如果添加上where条件,那么就是筛选:
```
@DB(table = User.class)
@FIND(where = "name = ? and (age > ? or sex = ?)",limit = 10,orderBy = "age desc")
DbResult<User> findUser(String name, int age, String sex);
```
先不用关注limit和orderby,这里主要是where,where里面的变量必须用`?`来标识,同时方法的参数必须跟`?`的个数一致。and和or用来条件连接,`()`用来表示优先级。
> 其中需要注意的是,=操作是支持String, Integer,Date;>,<,>=,<=操作符支持Integer和Date,in操作符支持List,contains操作符支持String,like操作符支持String,notnull和null支持String
例子如下:
```
@DB(table = User.class)
@FIND(where = "name in ?",limit = 10)
DbResult<User> findUsers(List<String> users);
```
```
@DB(table = User.class)
@FIND(where = "name in ?")
DbResult<User> findUserByIn(List<String> users);
```
```
@DB(table = User.class)
@FIND(where = "name contains ?",distinct = "name")
DbResult<User> findUserByContains(String name);
```
@DB(table = User.class)
@FIND(where = "name like ? and age > ?",distinct = "name")
DbResult<User> findUserByLike(String name, int age);
```
@DB(table = User.class)
@FIND(where = "? notnull",limit = 2)
DbResult<User> findUserByNotNull(String name);
```
2.方法调用如下:
```
mApiDataBase.findUser("sharkchao", 20, "男")
.registerDbFindCallBack(new DbResult.DbFindCallBack<User>() {
@Override
public void onFirstFindResult(RealmResults<User> realmResults) {
UserData.setmResults(realmResults);
Toast.makeText(MainActivity.this, "成功!"+ realmResults.size(), Toast.LENGTH_SHORT).show();
}
@Override
public void onChange(RealmResults<User> realmResults) {
}
});
```
查询都是异步执行的,所以不用担心会阻塞主线程。其中onFirstFindResult()回调是第一次查询的回调。onChange()方法是查询到的集合发生变化时(比如被修改或者被添加)会调用。
### 6.2 去重查询
查询方法定义如下:
```
@DB(table = User.class)
@FIND(where = "name contains ?",distinct = "name")
DbResult<User> findUserByContains(String name);
```
其中distinct就是标识需要去重的字段。调用如6.1
### 6.3 排序查询
查询方法定义如下:
```
@DB(table = User.class)
@FIND(where = "name = ? and (age > ? or sex = ?)",limit = 10,orderBy = "age desc")
DbResult<User> findUser(String name, int age, String sex);
```
其中orderBy就是标识需要按照什么字段排序,其中desc用来标识降序排序,asc用来标识升序排序。当然不写的话默认就是升序排序。调用如6.1
### 6.4 limit限制条数
查询方法定义如下:
```
@DB(table = User.class)
@FIND(where = "name in ?",limit = 10)
DbResult<User> findUsers(List<String> users);
```
其中limit为了标识需要限制结果返回多少条。调用如6.1
### 6.5 其他如:sum,min,max,average
当查询结果返回为RealmResults<T>的时候,还可以调用如上几个方法对结果集的某个字段进行操作,如下所示:
```
RealmResults<User> results = realm.where(User.class).findAll();
long sum = results.sum("age").longValue();
long min = results.min("age").longValue();
long max = results.max("age").longValue();
double average = results.average("age");
long matches = results.size();
```
## 7.删除数据
删除数据目前两只方式:
1)通过@DELETE注解进行删除。
2)通过查询操作先查询出RealmResult,在RealmResult上进行删除操作。
### 7.1通过@DELETE注解来删除
先定义接口方法:
```
@DB(table = User.class)
@DELETE(where = "name = ?")
DbResult deleteUsersByQuery();
```
再执行删除操作:
```
mApiDataBase.deleteUsersByQuery().registerCallback(new DbResult.DbResultCallback() {
@Override
public void onSuccess(int count) {
Toast.makeText(MainActivity.this, "deleteUsersByQuery成功!"+count, Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable error) {
Toast.makeText(MainActivity.this, "deleteUsersByQuery失败"+error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
```
### 7.2通过查询操作来删除
定义查询接口:
```
@DB(table = User.class)
@FIND(where = "name in ?")
DbResult<User> findUserByIn(List<String> users);
```
在查询回调中执行删除操作
```
List<String> users = new ArrayList<>();
users.add("yuzhijun");
users.add("sharkchao");
mApiDataBase.findUserByIn(users).registerDbFindCallBack(new DbResult.DbFindCallBack<User>() {
@Override
public void onFirstFindResult(RealmResults<User> realmResults) {
if (realmResults.size() > 0){
realmResults.getRealm().executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realmResults.deleteAllFromRealm();
}
});
}else {
Toast.makeText(MainActivity.this, "realmResults为空", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onChange(RealmResults<User> realmResults) {
}
});
```
## 8.更新数据
更新数据时如果数据库中没有此条数据,则您注册的监听DbResult.DbResultCallback会回调onError()。如何注册监听下文会有详解。
更新数据目前两只方式:
1)通过@UPDATE注解进行更新。
2)通过查询操作先查询出RealmResult,在RealmResult上进行更新操作。
### 8.1通过@UPDATE注解来更新
先在接口中定义方法:
```
@DB(table = User.class)
@UPDATE(where = "name = ?",set = "name = ? and age = ?")
DbResult updateUsersByQuery(String oldName,String newName,String age);
```
然后执行更新操作:
```
mApiDataBase.updateUsersByQuery("sharkchao","小红","100").registerCallback(new DbResult.DbResultCallback() {
@Override
public void onSuccess(int count) {
Toast.makeText(MainActivity.this, "updateUsersByQuery成功!"+count, Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable error) {
Toast.makeText(MainActivity.this, "updateUsersByQuery失败"+error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
```
### 8.2通过查询操作来更新
先在接口中定义方法:
```
@DB(table = User.class)
@FIND(where = "name in ?")
DbResult<User> findUserByIn(List<String> users);
```
然后在返回结果中执行更新操作,针对对象的set操作都会直接更新到数据库中
```
List<String> users = new ArrayList<>();
users.add("yuzhijun");
users.add("sharkchao");
mApiDataBase.findUserByIn(users).registerDbFindCallBack(new DbResult.DbFindCallBack<User>() {
@Override
public void onFirstFindResult(RealmResults<User> realmResults) {
if (realmResults.size() > 0){
realmResults.getRealm().executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realmResults.get(0).setName("刘超");
Toast.makeText(MainActivity.this, "更新成功!", Toast.LENGTH_SHORT).show();
}
});
}else {
Toast.makeText(MainActivity.this, "realmResults为空", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onChange(RealmResults<User> realmResults) {
}
});
```
## 9. 返回结果及监听
插入,更新,删除,查询都会返回DbResult,
其中插入,更新,删除需要注册DbResultCallback监听:
如果操作成功,会返回操作的总个数,如果失败会返回错误原因
代码如下:
```
mApiDataBase.saveOrUpdateUsersByArray(users).registerCallback(new DbResult.DbResultCallback() {
@Override
public void onSuccess(int count) {
Toast.makeText(MainActivity.this, "成功!"+count, Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable error) {
Toast.makeText(MainActivity.this, "失败"+error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
```
查询操作需要注册DbFindCallBack监听,第一次返回结果会回调onFirstFindResult(RealmResults<User> realmResults),之后对realmResults的操作都会执行到onChange(RealmResults<User> realmResults)。代码如下:
```
mApiDataBase.findUserByIn(users).registerDbFindCallBack(new DbResult.DbFindCallBack<User>() {
@Override
public void onFirstFindResult(RealmResults<User> realmResults) {
UserData.setmResults(realmResults);
Toast.makeText(MainActivity.this, "成功!"+ realmResults.size(), Toast.LENGTH_SHORT).show();
}
@Override
public void onChange(RealmResults<User> realmResults) {
Toast.makeText(MainActivity.this, "变化!"+ realmResults.size(), Toast.LENGTH_SHORT).show();
}
});
```
## 10.数据库升级
1.数据库升级需要在ApiServiceModule中的provideUStorage方法中修改版本号,默认版本为0,如果不配置migration则数据库会先删除再重建,数据不会保留。
```
private UStorage provideUStorage(){
return new UStorage.Builder()
.setSchemaVersion(1)
.build();
}
```
2.如果想数据库升级同时保留表数据则需要继承BaseMigration,使用方法如下:
```
public class CustomMigration extends BaseMigration {
@Override
public void upgrade(DynamicRealm realm, long oldVersion, long newVersion) {
RealmSchema schema = realm.getSchema();
if (oldVersion == 0 && newVersion == 1){
RealmObjectSchema user = schema.get("User");
user.addField("sex",String.class,FieldAttribute.REQUIRED)
.transform(new RealmObjectSchema.Function() {
@Override
public void apply(DynamicRealmObject obj) {
obj.set("sex","男");
}
});
oldVersion++;
}else if (oldVersion == 1 && newVersion == 2){
RealmObjectSchema user = schema.get("User");
user.removeField("sex");
oldVersion++;
}
}
}
```
如果您想查看BaseMigration 的具体使用细节,请查看:[版本升级](https://www.jianshu.com/p/37af717761cc) (这篇文章会有比较详细的版本升级内容)
## 11.注意事项
通过查询之后的结果来执行更新或删除操作时,具体的操作应该放在事务之中,模板如下:
```
List<String> users = new ArrayList<>();
users.add("yuzhijun");
users.add("sharkchao");
mApiDataBase.findUserByIn(users).registerDbFindCallBack(new DbResult.DbFindCallBack<User>() {
@Override
public void onFirstFindResult(RealmResults<User> realmResults) {
if (realmResults.size() > 0){
realmResults.getRealm().executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realmResults.get(0).setName("刘超");
Toast.makeText(MainActivity.this, "更新成功!", Toast.LENGTH_SHORT).show();
}
});
}else {
Toast.makeText(MainActivity.this, "realmResults为空", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onChange(RealmResults<User> realmResults) {
}
});
```
## 12.key-value形式存储(类sharepreference)
### 12.1存储
存储数据到本地文件中,需要用到@JSON进行标识,具体支持的方式如下:
#### 1.存储对象类型
```
@JSON(key = "JSON_KEY",convert = User.class)
boolean saveJson(User user);
```
存储的key为自己定义的字符串,如果是自定义对象类型需要在convert中进行标识,这里就是User.class。
对结果进行操作实例如下:
```
DbResult<User> user = mApiDataBase.getJson();
if (null != user && null != user.getResult()){
System.out.println(user.getResult().getName());
}
```
#### 2.存储对象集合类型
```
@JSON(key = "JSON_ARRAY",convert = User.class)
boolean saveJsonArray(List<User> users);
```
存储对象集合和存储对象的方式相同,只是参数传进去的是List<T>类型。
#### 3.存储基本类型
```
@JSON(key = "JSON_STR")
boolean saveStr(String str);
@JSON(key = "JSON_INT")
boolean saveInt(int ints);
@JSON(key = "JSON_BOOL")
boolean saveBool(boolean booleans);
```
存储基本类型不需要指定convert,只要定义一个key,然后直接设置进相应的参数即可。
### 12.2 获取
获取存储进本地的数据需要使用@GETJSON注解,具体如下:
#### 1.获取对象类型的数据
```
@GETJSON(key = "JSON_KEY",convert=User.class)
DbResult<User> getJson();
```
其中key就是对应前面存储的key,对象类型的话需要指明convert为具体的对象类型,这里为User.class。
#### 2.获取对象集合类型数据
```
@GETJSON(key = "JSON_ARRAY",convert = User[].class)
DbResult<List<User>> getJsonArray();
```
唯一与对象类型不同的是convert这个地方为具体对象的数组类型。这里为User[].class
#### 3.获取基本类型数据
```
@GETJSON(key = "JSON_STR")
DbResult<String> getStr();
@GETJSON(key="JSON_BOOL",convert = Boolean.class)
DbResult<Boolean> getBool();
@GETJSON(key = "JSON_INT",convert = Integer.class)
DbResult<Integer> getInt();
```
同样这里需要指定基本的类型,如果是String的话可以不写,因为默认就是String类型。
## 13.mock网络返回数据
这里是兼容retrofit形式的网络访问,用户只需要在获取retrofit的里面添加库里面的callAdapter和convert即可,具体如下:
```
new Retrofit.Builder()
.addCallAdapterFactory(MockCallAdapterFactory.create(context))
.addConverterFactory(MockConverterFactory.create())
.baseUrl("http://test.com")
.build();
```
操作非常简单。同时要注意的是,在你准备本地json的时候,要注意本地json文件名称跟定义的接口相同:
```
@GET("/getUser")
Call<User> getUser();
```
如果这个地方@GET注解里面的url为getUser(这里只会匹配最后一个/后面的名字),那么本地json名字也要取成getUser.json。然后就可以正常使用了
