Java SDK
数据引擎提供不跨网络,通过模型访问数据的 Java SDK。为开发者提供易用的访问数据的接口,通过接口访问 DBRest 的数据查询功能、插入/更新及删除功能。
- com.justep.tools.mybatis.DbrestWrapper:用于生成查询的过滤条件,完全基于 MyBatis-Plus 的 QueryWrapper,并扩展了关联查询和子查询的部分。DbrestWrapper扩展的部份需要Dbrest的支持,当前DbrestWrapper不支持实体类,如:qw.lambda().eq(User::getName, "1")。
- com.justep.tools.mybatis.DbrestUtil:用于查询、插入、更新、删除数据。虽然DbrestWrapper不支持实体类,但DbrestUtil中是可以以实体类为参数或返回值的。
- com.justep.tools.DbrestResult:返回结果
使用前先添加依赖设置
引入系统工具类
组名称 | 名称 | 版本号 |
---|---|---|
com.justep | tools | 1.0.0 |
QueryWrapper 方法
查询方法
方法名 | 含义 | 代码 | 案例 |
---|---|---|---|
select | 设置查询字段 | select(String... sqlSelect) | 例: select("id", "name", "age") |
groupBy | 分组:GROUP BY 字段, ... | groupBy(R... columns) groupBy(boolean condition, R... columns) |
例: groupBy("id", "name") --->group by id,name |
orderByAsc | 排序:ORDER BY 字段, ... ASC | orderByAsc(R... columns) orderByAsc(boolean condition, R... columns) |
例: orderByAsc("id", "name") --->order by id ASC,name ASC |
orderByDesc | 排序:ORDER BY 字段, ... DESC | orderByDesc(R... columns) orderByDesc(boolean condition, R... columns) |
例: orderByDesc("id", "name") --->order by id DESC,name DESC |
orderBy | 排序:ORDER BY 字段, ... | orderBy(boolean condition, boolean isAsc, R... columns) | 例: orderBy(true, true, "id", "name") --->order by id ASC,name ASC |
having | HAVING ( sql语句 ) | having(String sqlHaving, Object... params) having(boolean condition, String sqlHaving, Object... params) |
例: having("sum(age) > 10") --->having sum(age) > 10 例: having("sum(age) > {0}", 11) --->having sum(age) > 11 |
条件操作符
操作符 | 含义 | 代码 | 案例 |
---|---|---|---|
eq | 等于 = | eq(R column, Object val) eq(boolean condition, R column, Object val) |
例: eq("name", "老王") --->name = '老王' |
ne | 不等于 <> | ne(R column, Object val) ne(boolean condition, R column, Object val) |
例: ne("name", "老王") --->name <> '老王' |
gt | 大于 > | gt(R column, Object val) gt(boolean condition, R column, Object val) |
例: gt("age", 18) --->age > 18 |
ge | 大于等于 >= | ge(R column, Object val) ge(boolean condition, R column, Object val) |
例: ge("age", 18) --->age >= 18 |
lt | 小于 < | lt(R column, Object val) lt(boolean condition, R column, Object val) |
例: lt("age", 18) --->age < 18 |
le | 小于等于 <= | le(R column, Object val) le(boolean condition, R column, Object val) |
例: le("age", 18) --->age <= 18 |
like | LIKE '%值%' | like(R column, Object val) like(boolean condition, R column, Object val) |
例: like("name", "王") --->name like '%王%' |
notLike | NOT LIKE '%值%' | notLike(R column, Object val) notLike(boolean condition, R column, Object val) |
例: notLike("name", "王") --->name not like '%王%' |
likeLeft | LIKE '%值' | likeLeft(R column, Object val) likeLeft(boolean condition, R column, Object val) |
例: likeLeft("name", "王") --->name like '%王' |
likeRight | LIKE '值%' | likeRight(R column, Object val) likeRight(boolean condition, R column, Object val) |
例: likeRight("name", "王") --->name like '王%' |
between | BETWEEN 值1 AND 值2 | between(R column, Object val1, Object val2) between(boolean condition, R column, Object val1, Object val2) |
例: between("age", 18, 30) --->age between 18 and 30 |
notBetween | NOT BETWEEN 值1 AND 值2 | notBetween(R column, Object val1, Object val2) notBetween(boolean condition, R column, Object val1, Object val2) |
例: notBetween("age", 18, 30) --->age not between 18 and 30 |
isNull | 字段 IS NULL | isNull(R column) isNull(boolean condition, R column) |
例: isNull("name") --->name is null |
isNotNull | 字段 IS NOT NULL | isNotNull(R column) isNotNull(boolean condition, R column) |
例: isNotNull("name") --->name is not null |
in | 字段 IN (value.get(0), value.get(1), ...) | in(R column, Collection <?> value)` value) | 例: in("age",{1,2,3}) -->age in (1,2,3) |
in | 字段 IN (v0, v1, ...) | in(R column, Object... values) in(boolean condition, R column, Object... values) |
例: in("age", 1, 2, 3) --->age in (1,2,3) |
notIn | 字段 NOT IN (value.get(0), value.get(1), ...) | notIn(R column, Collection <?> value)notIn(boolean condition, R column, Collection<?> value) |
例: notIn("age",{1,2,3}) --->age not in (1,2,3) |
notIn | 字段 NOT IN (v0, v1, ...) | notIn(R column, Object... values) notIn(boolean condition, R column, Object... values) |
例: notIn("age", 1, 2, 3) --->age not in (1,2,3) |
inSql | 字段 IN ( 不支持sql语句 ) | inSql(R column, String inValue) inSql(boolean condition, R column, String inValue) |
例: inSql("age", "1,2,3,4,5,6") --->age in (1,2,3,4,5,6) |
notInSql | 字段 NOT IN ( 不支持sql语句 ) | notInSql(R column, String inValue) notInSql(boolean condition, R column, String inValue) |
例: notInSql("age", "1,2,3,4,5,6") --->age not in (1,2,3,4,5,6) |
or | 拼接 OR 注意事项:主动调用 or 表示紧接着下一个方法不是 用 and 连接(不调用 or 则默认为使用 and 连接) |
or() or(boolean condition) |
例: eq("id",1).or().eq("name","老王") --->id = 1 or name = '老王' |
or | OR 嵌套 | or(Consumer <Param> consumer)or(boolean condition, Consumer <Param> consumer) |
例: or(i -> i.eq("name", "李白").ne("status", "活着")) --->or (name = '李白' and status <> '活着') |
and | AND 嵌套 | and(Consumer <Param> consumer)and(boolean condition, Consumer <Param> consumer) |
例: and(i -> i.eq("name", "李白").ne("status", "活着")) --->and (name = '李白' and status <> '活着') |
nested | 正常嵌套 不带 AND 或者 OR | nested(Consumer <Param> consumer)nested(boolean condition, Consumer <Param> consumer) |
例: nested(i -> i.eq("name", "李白").ne("status", "活着")) --->(name = '李白' and status <> '活着') |
目前不支持的操作符有:func、apply、last、exists、notExists。
操作符 | 含义 | 代码 | 案例 |
---|---|---|---|
func | func 方法(主要方便在出现 if...else 下调用不同方法能不断链) | func(Consumer <Children> consumer)func(boolean condition, Consumer <Children> consumer) |
例: func(i -> if(true) {i.eq("id", 1)} else {i.ne("id", 1)}) |
DbrestWrapper 方法
DbrestWrapper 接口提供与 QueryWrapper 类似的接口,目的是为用户提供一个易用的访问数据的接口,通过这个接口访问 DbRest 的数据查询功能
构造方法
定义如下
方法:
DbrestWrapper(final String serviceName, final String moduleName, final String dataModelName)
参数:
serviceName:{String} - 服务名
moduleName:{String} - 模块名
dataModelName:{String} - 数据模型名
返回值:
DbrestWrapper 对象
例:查询订单金额大于100,订单编号等于123或22的数据,返回 fid。orderDate,orderNo 三列,先按 orderNo 排升序,再按 orderDate 排降序,代码如下:
DbrestWrapper<?> wrapper = (DbrestWrapper<?>)new DbrestWrapper <String>("order", "main", "saleOrder");
wrapper.select("fid", "orderDate", "orderNo");
wrapper.gt("totalMoney",100);
wrapper.and(i->i.eq("orderNo","123").or().eq("orderNo","22"));
wrapper.orderByAsc("orderNo").orderByDesc("orderDate");
例:以订单日期分组,统计订单总金额,代码如下:
DbrestWrapper<?> wrapper = (DbrestWrapper<?>)new DbrestWrapper <String>("order", "main", "saleOrder");
wrapper.select("orderDate", "sum(totalMoney)" );
wrapper.groupBy("orderDate");
例:以订单日期分组,统计count(creatorID)为1的订单总金额,代码如下:
DbrestWrapper<?> wrapper = (DbrestWrapper<?>)new DbrestWrapper <String>("order", "main", "saleOrder");
wrapper.select("orderDate", "sum(totalMoney)" );
wrapper.groupBy("orderDate");
wrapper.having("count(creatorID)=eq.1");
关联查询方法
方法 | 含义 | 代码 | 案例 |
---|---|---|---|
setMainTableAlias | 设置主表的别名 | setMainTableAlias(String alias) | 例: setMainTableAlias("A") |
setLeftAliasUsed | 设置使用的左表 | setLeftAliasUsed(String alias) | 例: setLeftAliasUsed("B") |
leftJoin | 左连接 | leftJoin(String dataModelName) | 例: leftJoin("customer") |
rightJoin | 右连接 | rightJoin(String dataModelName) | 例: rightJoin("customer") |
innerJoin | 内连接 | innerJoin(String dataModelName) | 例: innerJoin("customer") |
fullJoin | 全连接 | fullJoin(String dataModelName) | 例: fullJoin("customer") |
alias | 设置右表的别名 | alias(String alias) | 例: alias("B") |
on | 关联条件 注意事项:on 上的表达方式只能使用 Dbrest 的格式 left_table_field.op.right_table_field op 可用的值与 QueryWrapper 中可用的条件操作相同 | on(String filter) | 例: on("fid.eq.fid")--->left.fid = right.fid 例: on("fid.eq.fid").on("name.lt.name")--->left.fid = right.fid and left.name |
例:通过销售订单的客户 id 列左关联客户的 id 列,查询出客户名称列,代码如下:
DbrestWrapper<?> wrapper = (DbrestWrapper<?>)new DbrestWrapper <String>("order", "main", "saleOrder");
wrapper.select("fid", "orderDate", "orderNo", "name");
wrapper.setMainTableAlias("A");
wrapper.leftJoin("customer").alias("B").on("customId.eq.id");
例:通过销售订单的客户 id 列左关联客户的 id 列,再通过客户的项目 id 列左关联项目的 id 列,查询出客户名称、项目名称列,代码如下:
DbrestWrapper<?> wrapper = (DbrestWrapper<?>)new DbrestWrapper <String>("order", "main", "saleOrder");
wrapper.select("fid", "orderDate", "orderNo", "name", "projectName");
wrapper.setMainTableAlias("A");
wrapper.leftJoin("customer").alias("B").on("customId.eq.id");
wrapper.leftJoin("project").alias("C").on("projectId.eq.id");
例:通过 orgs 的 org_id 列左关联 authorize 的 subject_id 列,再通过 authorize 的 role_id 列左关联 role 的 id 列,代码如下:
DbrestWrapper<?> wrapper = (DbrestWrapper<?>) new DbrestWrapper("entry","uaa","orgs");
wrapper.select("A.fid as fid","A.code as code","A.name as name","C.code as rolecode","C.name as rolename");
wrapper.setMainTableAlias("A");
wrapper.leftJoin("comp/authorize/authorize").alias("B").on("org_id.eq.subject_id");
wrapper.setLeftAliasUsed("B");
wrapper.leftJoin("comp/authorize/role").alias("C").on("role_id.eq.id");
例:通过 main 服务模块中 info 的 code 列左关联 oa 服务模块中 basedata 的 no 列,代码如下:
DbrestWrapper<?> wrapper = (DbrestWrapper<?>) new DbrestWrapper("vuedemo","main","info");
wrapper.select("A.fid as fid","A.title as title","A.content as content","A.person as person","B.name as typename");
wrapper.setMainTableAlias("A");
wrapper.leftJoin("oa/basedata").alias("B").on("code.eq.no");
例:通过users的id列左关联orgs的id列,然后在通过orgs的code列like查询users的username列,即关联查询后再设置其他的条件,代码如下:
DbrestWrapper<?> userListWrapper = (DbrestWrapper<?>) new DbrestWrapper("entry","uaa","users");
userListWrapper.select("o.fid as fid","u.name as name","u.username as username");
userListWrapper.setMainTableAlias("u");
userListWrapper.leftJoin("orgs").alias("o").on("id.eq.id");
userListWrapper.like("o.code","field:u.username");
子查询方法和常量
方法 | 含义 | 代码 | 案例 |
---|---|---|---|
addSubQueryWrapper | 添加子查询 | addSubQueryWrapper(String subQueryName,DbrestWrapper wrapper) | 例:addSubQueryWrapper("subquery1", subquery1) |
SubQueryPrefix | 常量 | DbrestWrapper.SubQueryPrefix="$subquery:" | 例:DbrestWrapper.SubQueryPrefix |
例:使用一个子查询,查询订单明细中包括办公桌的订单,代码如下:
DbrestWrapper<?> wrapper = (DbrestWrapper<?>)new DbrestWrapper <String>("order", "main", "saleOrder");
DbrestWrapper<?> subquery0 = new DbrestWrapper <String>("order", "main", "saleOrderDetail");
subquery0.select("saleOrder");
subquery0.eq("product","办公桌");
wrapper.in("fid", DbrestWrapper.SubQueryPrefix + "subquery0");
wrapper.addSubQueryWrapper("subquery0", subquery0);
例:使用两个子查询,查询订单明细中包括办公桌的,且客户类型为 vip 的订单,代码如下:
DbrestWrapper<?> wrapper = (DbrestWrapper<?>)new DbrestWrapper <String>("order", "main", "saleOrder");
DbrestWrapper<?> subquery0 = new DbrestWrapper <String>("order", "main", "saleOrderDetail");
subquery0.select("saleOrder");
subquery0.eq("product","办公桌");
wrapper.in("fid", DbrestWrapper.SubQueryPrefix + "subquery0");
wrapper.addSubQueryWrapper("subquery0", subquery0);
DbrestWrapper<?> subquery1 = new DbrestWrapper<String>("order", "main", "customer");
subquery1.select("id");
subquery1.eq("customType","vip");
wrapper.in("customId", DbrestWrapper.SubQueryPrefix + "subquery1");
wrapper.addSubQueryWrapper("subquery1", subquery1);
DbrestUtil 方法
DbrestUtil 类,为用户提供查询数据、插入/更新数据、删除数据的方法。
查询全部数据
查询全部数据,返回 List
方法:
public static <T> List <T> selectAll(final DbrestWrapper queryWrapper, final Class <T> entityType);
描述:
查询全部数据
参数:
queryWrapper:{DbrestWrapper} - DbrestWrapper 对象
entityType:{Class} - 返回对象类型
返回值:
List
例:查询 saleOrder 数据集的数据,代码如下:
DbrestWrapper<?> wrapper = (DbrestWrapper<?>)new DbrestWrapper <String>("order", "main", "saleOrder");
List <SaleOrder> list = DbrestUtil.selectAll(wrapper, SaleOrder.class);
查询分页数据
查询分页数据,返回 Page
方法:
public static <T> Page<T> selectPage(final DbrestWrapper queryWrapper, final Class<T> entityType, final PageRequest pageRequest);
描述:
查询分页数据
参数:
queryWrapper:{DbrestWrapper} - DbrestWrapper 对象
entityType:{Class} - 返回对象类型
pageRequest:{PageRequest} - 分页对象
返回值:
Page
例:一页取20条记录,查询第一页的数据,代码如下:
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
public Page<SaleOrder> selectPage() throws Exception {
DbrestWrapper <?> wrapper = (DbrestWrapper<?>)new DbrestWrapper <String>("order", "main", "saleOrder");
// 1. mybatis plus 从1开始 2. spring data jpa 从0开始 3. 平台是从1开始 4. 前端是从1开始
com.justep.cloud.data.PageRequest pageRequest = new com.justep.cloud.data.PageRequest(1, 20);
com.justep.cloud.data.Page <SaleOrder> page = DbrestUtil.selectPage( wrapper, SaleOrder.class, pageRequest);
return new PageImpl<>(page.getContent(), new PageRequest(0, 20), page.getTotal());
}
查询数据
查询数据,返回 DbrestResult
方法:
public static DbrestResult get(final DbrestWrapper queryWrapper, final PageRequest pageRequest);
描述:
查询数据
参数:
queryWrapper:{DbrestWrapper} - DbrestWrapper 对象
pageRequest:{PageRequest} - 分页对象
返回值:
DbrestResult
例:查询 saleOrder 数据集的数据,代码如下:
DbrestWrapper<?> wrapper = (DbrestWrapper<?>)new DbrestWrapper <String>("order", "main", "saleOrder");
DbrestResult ret = DbrestUtil.get(wrapper, null);
查询附件流
方法:
public static Stream getStream(final DbrestWrapper queryWrapper);
描述:
查询附件流
参数:
queryWrapper:{DbrestWrapper} - DbrestWrapper 对象
返回值:
Stream
例:获取订单编号22的附件(列标识:files)中的第一个文件的文件流,代码如下:
DbrestWrapper<?> wrapper = (DbrestWrapper<?>)new DbrestWrapper <String>("order", "main", "saleOrder");
wrapper.eq("orderNo","22");
wrapper.stream("files", "0");
DbrestUtil.getStream(wrapper);
插入/更新数据
方法:
public static <T> DbrestResult upsert(final String serviceName, final String moduleName, final String dataModelName, final List<T> data);
public static DbrestResult upsert(final String serviceName, final String moduleName, final String dataModelName, final JSONArray data);
描述:
插入/更新数据,当主键值不存在时执行新增,否则执行更新
参数:
serviceName:{String} - 服务名
moduleName:{String} - 模块名
dataModelName:{String} - 数据集名
data:{List | JSONArray} - 插入或更新的数据
返回值:
DbrestResult 对象
例:给 saleOrder 插入新数据,代码如下:
SaleOrder so = new SaleOrder();
so.setFid("java1");
so.setOrderNo("java2");
List<SaleOrder> soList = new ArrayList <SaleOrder>();
soList.add(so);
DbrestResult ret = DbrestUtil.upsert("order", "main", "saleOrder", soList);
删除数据
提供两种删除数据的方法:delete 方法根据数据删除;deleteByCondition 方法根据条件删除,分别说明如下
方法:
public static <T> DbrestResult delete(final String serviceName, final String moduleName, final String dataModelName, final List<T> data);
public static DbrestResult delete(final String serviceName, final String moduleName, final String dataModelName, final JSONArray data);
描述:
删除数据
参数:
serviceName:{String} - 服务名
moduleName:{String} - 模块名
dataModelName:{String} - 数据集名
data:{List | JSONArray} - 删除的数据
返回值:
DbrestResult 对象
方法:
public static DbrestResult deleteByCondition(final String serviceName, final String moduleName, final String dataModelName, final String dbrestCondition)
描述:
根据条件删除数据
参数:
serviceName:{String} - 服务名
moduleName:{String} - 模块名
dataModelName:{String} - 数据集名
dbrestCondition:{String} - 删除条件
返回值:
DbrestResult 对象
例:删除 saleOrder 中 fid 等于5的数据,代码如下:
DbrestResult ret = DbrestUtil.deleteByCondition("order", "main", "saleOrder","fid=eq.5");
传入请求头
上面的方法都支持最后加一个参数 Map<String, String> headers
,用于传入请求头。例如:不校验数据权限
Map<String, String> headers = new HashMap<String,String>();
headers.put("X-DbProxy-DisableSqlPermissions", "true");
DbrestUtil.selectAll(wrapper, SaleOrder.class, headers);
DbrestResult 方法
获取执行结果 String 类型
方法:
public String getResult();
描述:
获取执行结果,返回字符串
返回值:
String
例: 获取查询结果数据,返回 String,代码如下:
DbrestResult ret = DbrestUtil.get(wrapper, null);
return ret.getResult();
获取执行结果 JSON 类型
方法:
public JSONObject toJson();
描述:
获取执行结果,返回 JSONObject
返回值:
JSONObject
例:获取查询结果数据,返回 JSON 对象,代码如下:
DbrestResult ret = DbrestUtil.get(wrapper, null);
JSONObject json = ret.toJson();
获取响应头
方法:
public Map<String,List<String>> getResponseHeaders();
描述:
获取响应头
返回值:
Map<String,List<String>>
例:获取查询请求响应头中的 Content-Range 的值,代码如下:
DbrestResult ret = DbrestUtil.get(wrapper, null);
return ret.getResponseHeaders().get("Content-Range").get(0);