SDK下载地址
如果是Maven管理,可以在pom.xml中加入如下依赖:
<dependency>
<groupId>com.kingdeegroupId>
<artifactId>k3cloud-webapiartifactId>
<version>1.0.0version>
<scope>systemscope>
<systemPath>${project.basedir}/lib/k3cloud-webapi-sdk7.9.2.jarsystemPath>
dependency>
起步配置有官方教程:查看官方指南
官网只提供了一些查询数据方法。对于java代码来说写起来很不舒服。下面我做了一些工具类。
3.1 序列化SFunction
@FunctionalInterface
public interface SFunction<T, R> extends Function<T, R>, Serializable {
}
3.2 序列化解析类
public final class SFunctionParse {
/**
* 解析多个表达式
*
* @param functions
* @param
* @return
* @throws Exception
*/
public static final <T, R> String[] resolves(SFunction<T, R>... functions) {
String[] fileNames = new String[functions.length];
String fileName;
try {
for (int i = 0; i < functions.length; i++) {
SFunction<T, R> function = functions[i];
// 直接调用writeReplace
Method methods = function.getClass().getDeclaredMethod("writeReplace");
methods.setAccessible(true);
//反射调用
Object sl = methods.invoke(function);
SerializedLambda serializedLambda = (SerializedLambda) sl;
String methodName = serializedLambda.getImplMethodName();
String name = methodName.replace("get", "");
fileName = name.substring(0, 1).toLowerCase() + name.substring(1);
// 将_替换为.改成查询字段
fileName = fileName.replace("_", ".");
fileNames[i] = fileName;
}
} catch (Exception e) {
e.printStackTrace();
}
return fileNames;
}
/**
* 解析一个表达式
*
* @param function
* @param
* @return
* @throws Exception
*/
public static final <T, R> String resolve(SFunction<T, R> function) {
return resolves(function)[0];
}
}
3.3 @FomId注解类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface FormId {
String value() default "";
}
3.4 抽象构建类
public abstract class AbstractBuilder<T> {
/**
* 查询参数构造器
*/
protected List<String> fieldKeys = new ArrayList<>();
/**
* 过滤条件构造器
*/
protected StringBuilder filterStrBuilder = new StringBuilder();
/**
* 排序规则条件构造器
*/
protected StringBuilder orderBuilder = new StringBuilder();
/**
* 返回总行数
*/
protected int TopRowCount = 0;
/**
* 开始行索引
*/
protected int StartRow = 0;
/**
* 最大行数
*/
protected int Limit = 0;
protected final String LOGIC_AND = " AND ";
protected final String LOGIC_OR = " OR ";
/**
* 获取查询字段
*
* @return
*/
public abstract List<String> getFieldKeys();
/**
* 构建查询字段
*
* @return
*/
public abstract String buildFieldKeys();
/**
* 构造查询条件
*
* @return
*/
public abstract String buildFilter();
/**
* 构造排序条件
*
* @return
*/
public abstract String buildOrder();
/**
* 构建总行数
*
* @return
*/
public abstract int buildTopRowCount();
/**
* 构建起始行数
*
* @return
*/
public abstract int buildStartRow();
/**
* 构建最大行数
*
* @return
*/
public abstract int buildLimit();
}
3.5 条件过滤构建器FilterRuleBuilder,类比mybatis
public class FilterRuleBuilder extends AbstractBuilder{
public FilterRuleBuilder() {
}
/**
* 逻辑关系,默认and
*/
protected String logic = LOGIC_AND;
/**
* 获取查询字段
*
* @return
*/
public List<String> getFieldKeys() {
return this.fieldKeys;
}
/**
* 切换and逻辑
*
* @return
*/
public FilterRuleBuilder and() {
this.logic = LOGIC_AND;
return this;
}
/**
* 列表查询字段
*
* @param fieldKeys
* @return
*/
public FilterRuleBuilder select(List<String> fieldKeys) {
this.fieldKeys = fieldKeys;
return this;
}
/**
* 查询具体类的所有字段:所有子字段用下划线代替,例如:FDocumentStatus.FCaption ==》FDocumentStatus_FCaption
*
* @param cls
* @return
*/
public FilterRuleBuilder selectAllFiled(Class cls) {
Field[] fields = cls.getDeclaredFields();
for (Field field : fields) {
String fieldName = field.getName().replace("_", ".");
select(fieldName);
}
return this;
}
/**
* 添加查询字段
*
* @param fieldKey
* @return
*/
public FilterRuleBuilder select(String fieldKey) {
fieldKeys.add(fieldKey);
return this;
}
/**
* 添加多个查询字段
*
* @param fieldKeys
* @return
*/
public FilterRuleBuilder select(String... fieldKeys) {
for (String fieldKey : fieldKeys) {
select(fieldKey);
}
return this;
}
/**
* 多字段排序
*
* @param fieldNames
* @return
*/
public FilterRuleBuilder orderBy(boolean isDesc, String... fieldNames) {
// 不为空加逻辑关系
if (orderBuilder.length() != 0) {
orderBuilder.append(",");
}
for (String fieldName : fieldNames) {
if (isDesc) {
orderBuilder.append(String.format("%s DESC,", fieldName));
} else {
orderBuilder.append(String.format("%s ASC,", fieldName));
}
}
// 删除最后一个字符
orderBuilder.deleteCharAt(orderBuilder.length() - 1);
return this;
}
/**
* 正序排序
*
* @param fieldName
* @return
*/
public FilterRuleBuilder orderByAsc(String fieldName) {
// 不为空加逻辑关系
if (orderBuilder.length() != 0) {
orderBuilder.append(",");
}
orderBuilder.append(String.format("%s ASC", fieldName));
return this;
}
/**
* 倒序排序
*
* @param fieldName
* @return
*/
public FilterRuleBuilder orderByDesc(String fieldName) {
// 不为空加逻辑关系
if (orderBuilder.length() != 0) {
orderBuilder.append(",");
}
orderBuilder.append(String.format("%s DESC", fieldName));
return this;
}
/**
* 切换or逻辑
*
* @return
*/
public FilterRuleBuilder or() {
logic = LOGIC_OR;
return this;
}
/**
* 等于构造
*
* @param fieldName
* @param value
* @return
*/
public FilterRuleBuilder eq(String fieldName, Object value) {
// 不为空加逻辑关系
if (filterStrBuilder.length() != 0) {
filterStrBuilder.append(logic);
}
// 字母或数字要加引号
if (value instanceof String || value instanceof Date) {
filterStrBuilder.append(String.format("(%s = '%s')", fieldName, value));
} else {
filterStrBuilder.append(String.format("(%s = %s)", fieldName, value));
}
return this;
}
/**
* 不等于构造
*
* @param fieldName
* @param value
* @return
*/
public FilterRuleBuilder ne(String fieldName, Object value) {
// 不为空加逻辑关系
if (filterStrBuilder.length() != 0) {
filterStrBuilder.append(logic);
}
// 字母或数字要加引号
if (value instanceof String || value instanceof Date) {
filterStrBuilder.append(String.format("(%s <> '%s')", fieldName, value));
} else {
filterStrBuilder.append(String.format("(%s <> %s)", fieldName, value));
}
return this;
}
/**
* 小于构造
*
* @param fieldName
* @param value
* @return
*/
public FilterRuleBuilder lt(String fieldName, Object value) {
// 不为空加逻辑关系
if (filterStrBuilder.length() != 0) {
filterStrBuilder.append(logic);
}
// 字母或数字要加引号
if (value instanceof String || value instanceof Date) {
filterStrBuilder.append(String.format("(%s < '%s')", fieldName, value));
} else {
filterStrBuilder.append(String.format("(%s < %s)", fieldName, value));
}
return this;
}
/**
* 大于构造
*
* @param fieldName
* @param value
* @return
*/
public FilterRuleBuilder gt(String fieldName, Object value) {
// 不为空加逻辑关系
if (filterStrBuilder.length() != 0) {
filterStrBuilder.append(logic);
}
// 字母或数字要加引号
if (value instanceof String || value instanceof Date) {
filterStrBuilder.append(String.format("(%s > '%s')", fieldName, value));
} else {
filterStrBuilder.append(String.format("(%s > %s)", fieldName, value));
}
return this;
}
/**
* 小于等于构造
*
* @param fieldName
* @param value
* @return
*/
public FilterRuleBuilder le(String fieldName, Object value) {
// 不为空加逻辑关系
if (filterStrBuilder.length() != 0) {
filterStrBuilder.append(logic);
}
// 字母或数字要加引号
if (value instanceof String || value instanceof Date) {
filterStrBuilder.append(String.format("(%s <= '%s')", fieldName, value));
} else {
filterStrBuilder.append(String.format("(%s <= %s)", fieldName, value));
}
return this;
}
/**
* 大于等于构造
*
* @param fieldName
* @param value
* @return
*/
public FilterRuleBuilder ge(String fieldName, Object value) {
// 不为空加逻辑关系
if (filterStrBuilder.length() != 0) {
filterStrBuilder.append(logic);
}
// 字母或数字要加引号
if (value instanceof String || value instanceof Date) {
filterStrBuilder.append(String.format("(%s >= '%s')", fieldName, value));
} else {
filterStrBuilder.append(String.format("(%s >= %s)", fieldName, value));
}
return this;
}
/**
* 模糊=构造
*
* @param fieldName
* @param value
* @return
*/
public FilterRuleBuilder like(String fieldName, Object value) {
// 不为空加逻辑关系
if (filterStrBuilder.length() != 0) {
filterStrBuilder.append(logic);
}
// 字母或数字要加引号
if (value instanceof String || value instanceof Date) {
filterStrBuilder.append("(" + fieldName + " LIKE '%" + value + "%')");
}
return this;
}
/**
* 模糊<>构造
*
* @param fieldName
* @param value
* @return
*/
public FilterRuleBuilder notLike(String fieldName, Object value) {
// 不为空加逻辑关系
if (filterStrBuilder.length() != 0) {
filterStrBuilder.append(logic);
}
// 字母或数字要加引号
if (value instanceof String || value instanceof Date) {
filterStrBuilder.append("(" + fieldName + " NOT LIKE '%" + value + "%')");
}
return this;
}
/**
* 模糊Left构造
*
* @param fieldName
* @param value
* @return
*/
public FilterRuleBuilder likeLeft(String fieldName, Object value) {
// 不为空加逻辑关系
if (filterStrBuilder.length() != 0) {
filterStrBuilder.append(logic);
}
// 字母或数字要加引号
if (value instanceof String || value instanceof Date) {
filterStrBuilder.append("(" + fieldName + " LIKE '%" + value + "')");
}
return this;
}
/**
* 模糊Right构造
*
* @param fieldName
* @param value
* @return
*/
public FilterRuleBuilder likeRight(String fieldName, Object value) {
// 不为空加逻辑关系
if (filterStrBuilder.length() != 0) {
filterStrBuilder.append(logic);
}
// 字母或数字要加引号
if (value instanceof String || value instanceof Date) {
filterStrBuilder.append("(" + fieldName + " LIKE '" + value + "%')");
}
return this;
}
/**
* between 连接
*
* @param fieldName
* @param startVal
* @param endVal
* @return
*/
public FilterRuleBuilder between(String fieldName, Object startVal, Object endVal) {
// 不为空加逻辑关系
if (filterStrBuilder.length() != 0) {
filterStrBuilder.append(logic);
}
// 字母或数字要加引号
if (startVal instanceof String || startVal instanceof Date) {
filterStrBuilder.append(String.format("(%s BETWEEN '%s'", fieldName, startVal));
} else {
filterStrBuilder.append(String.format("(%s BETWEEN %s", fieldName, startVal));
}
if (endVal instanceof String || endVal instanceof Date) {
filterStrBuilder.append(String.format(" AND '%s')", endVal));
} else {
filterStrBuilder.append(String.format(" AND '%s')", endVal));
}
return this;
}
/**
* netBetween 连接
*
* @param fieldName
* @param startVal
* @param endVal
* @return
*/
public FilterRuleBuilder notBetween(String fieldName, Object startVal, Object endVal) {
// 不为空加逻辑关系
if (filterStrBuilder.length() != 0) {
filterStrBuilder.append(logic);
}
// 字母或数字要加引号
if (startVal instanceof String || startVal instanceof Date) {
filterStrBuilder.append(String.format("(%s NOT BETWEEN '%s'", fieldName, startVal));
} else {
filterStrBuilder.append(String.format("(%s NOT BETWEEN %s", fieldName, startVal));
}
if (endVal instanceof String || endVal instanceof Date) {
filterStrBuilder.append(String.format(" AND '%s')", endVal));
} else {
filterStrBuilder.append(String.format(" AND '%s')", endVal));
}
return this;
}
/**
* 为空构造
*
* @param fieldName
* @return
*/
public FilterRuleBuilder isNull(String fieldName) {
// 不为空加逻辑关系
if (filterStrBuilder.length() != 0) {
filterStrBuilder.append(logic);
}
filterStrBuilder.append(String.format("(%s IS NULL)", fieldName));
return this;
}
/**
* 构建查询字段
*
* @return
*/
public String buildFieldKeys() {
return String.join(",", fieldKeys);
}
/**
* 不为空构造
*
* @param fieldName
* @return
*/
public FilterRuleBuilder isNotNull(String fieldName) {
// 不为空加逻辑关系
if (filterStrBuilder.length() != 0) {
filterStrBuilder.append(logic);
}
filterStrBuilder.append(String.format("(%s IS NOT NULL)", fieldName));
return this;
}
/**
* 总行数
*
* @param topRowCount
* @return
*/
public FilterRuleBuilder topRowCount(int topRowCount) {
this.TopRowCount = topRowCount;
return this;
}
/**
* 起始行数
*
* @param startRow
* @return
*/
public FilterRuleBuilder startRow(int startRow) {
this.StartRow = startRow;
return this;
}
/**
* 最大行数,不可超过2000
*
* @param limit
* @return
*/
public FilterRuleBuilder limit(int limit) {
if (limit < 2000) {
this.Limit = limit;
} else {
this.Limit = 2000;
}
return this;
}
/**
* 构造查询条件
*
* @return
*/
@Override
public String buildFilter() {
if (filterStrBuilder.length() != 0) {
return this.filterStrBuilder.toString();
} else {
return "";
}
}
/**
* 构造排序条件
*
* @return
*/
@Override
public String buildOrder() {
if (orderBuilder.length() != 0) {
return this.orderBuilder.toString();
} else {
return "";
}
}
/**
* 构建总行数
*
* @return
*/
@Override
public int buildTopRowCount() {
return this.TopRowCount;
}
/**
* 构建起始行数
*
* @return
*/
@Override
public int buildStartRow() {
return this.StartRow;
}
/**
* 构建最大行数
*
* @return
*/
@Override
public int buildLimit() {
return this.Limit;
}
}
3.6 Builder,FilterRuleBuilder的增强类,仅对于类的构建器,限制字段字符串输入,优于输入字符串,类比Mybatis-Plus 的 Wrappers
public final class Builder<T> extends AbstractBuilder<T> {
/**
* 字段构建器,增强其功能
*/
private FilterRuleBuilder ruleBuilder;
/**
* class类
*/
private Class<T> cls;
public Builder(Class<T> cls) {
this.cls = cls;
this.ruleBuilder = new FilterRuleBuilder();
}
public Class<T> getObjClass() {
return cls;
}
/**
* 静态构造器
* @param cls
* @param
* @return
*/
public static final <T> Builder<T> builder(Class<T> cls){
return new Builder<>(cls);
}
public Builder<T> selectAll() {
ruleBuilder.selectAllFiled(cls);
return this;
}
public <R> Builder<T> select(SFunction<T, R>... fieldNames) {
ruleBuilder.select(SFunctionParse.resolves(fieldNames));
return this;
}
public <R> Builder<T> orderBy(boolean isDesc, SFunction<T, R>... fieldNames) {
ruleBuilder.orderBy(isDesc, SFunctionParse.resolves(fieldNames));
return this;
}
public <R> Builder<T> orderByAsc(SFunction<T, R> fieldName) {
ruleBuilder.orderByAsc(SFunctionParse.resolve(fieldName));
return this;
}
public <R> Builder<T> orderByDesc(SFunction<T, R> fieldName) {
ruleBuilder.orderByDesc(SFunctionParse.resolve(fieldName));
return this;
}
public <R> Builder<T> eq(SFunction<T, R> fieldName, Object value) {
ruleBuilder.eq(SFunctionParse.resolve(fieldName), value);
return this;
}
public <R> Builder<T> ne(SFunction<T, R> fieldName, Object value) {
ruleBuilder.ne(SFunctionParse.resolve(fieldName), value);
return this;
}
public <R> Builder<T> lt(SFunction<T, R> fieldName, Object value) {
ruleBuilder.lt(SFunctionParse.resolve(fieldName), value);
return this;
}
public <R> Builder<T> gt(SFunction<T, R> fieldName, Object value) {
ruleBuilder.gt(SFunctionParse.resolve(fieldName), value);
return this;
}
public <R> Builder<T> le(SFunction<T, R> fieldName, Object value) {
ruleBuilder.le(SFunctionParse.resolve(fieldName), value);
return this;
}
public <R> Builder<T> ge(SFunction<T, R> fieldName, Object value) {
ruleBuilder.ge(SFunctionParse.resolve(fieldName), value);
return this;
}
public <R> Builder<T> like(SFunction<T, R> fieldName, Object value) {
ruleBuilder.like(SFunctionParse.resolve(fieldName), value);
return this;
}
public <R> Builder<T> notLike(SFunction<T, R> fieldName, Object value) {
ruleBuilder.notLike(SFunctionParse.resolve(fieldName), value);
return this;
}
public <R> Builder<T> likeLeft(SFunction<T, R> fieldName, Object value) {
ruleBuilder.likeLeft(SFunctionParse.resolve(fieldName), value);
return this;
}
public <R> Builder<T> likeRight(SFunction<T, R> fieldName, Object value) {
ruleBuilder.likeRight(SFunctionParse.resolve(fieldName), value);
return this;
}
public <R> Builder<T> between(SFunction<T, R> fieldName, Object startVal, Object endVal) {
ruleBuilder.between(SFunctionParse.resolve(fieldName), startVal, endVal);
return this;
}
public <R> Builder<T> notBetween(SFunction<T, R> fieldName, Object startVal, Object endVal) {
ruleBuilder.notBetween(SFunctionParse.resolve(fieldName), startVal, endVal);
return this;
}
public <R> Builder<T> isNull(SFunction<T, R> fieldName) {
ruleBuilder.isNull(SFunctionParse.resolve(fieldName));
return this;
}
public <R> Builder<T> isNotNull(SFunction<T, R> fieldName) {
ruleBuilder.isNotNull(SFunctionParse.resolve(fieldName));
return this;
}
public Builder<T> and() {
ruleBuilder.and();
return this;
}
public Builder<T> or() {
ruleBuilder.or();
return this;
}
public Builder<T> topRowCount(int topRowCount) {
ruleBuilder.topRowCount(topRowCount);
return this;
}
public Builder<T> startRow(int startRow) {
ruleBuilder.startRow(startRow);
return this;
}
public Builder<T> limit(int limit) {
ruleBuilder.limit(limit);
return this;
}
@Override
public List<String> getFieldKeys() {
return ruleBuilder.getFieldKeys();
}
@Override
public String buildFieldKeys() {
return ruleBuilder.buildFieldKeys();
}
@Override
public String buildFilter() {
return ruleBuilder.buildFilter();
}
@Override
public String buildOrder() {
return ruleBuilder.buildOrder();
}
@Override
public int buildTopRowCount() {
return ruleBuilder.buildTopRowCount();
}
@Override
public int buildStartRow() {
return ruleBuilder.buildStartRow();
}
@Override
public int buildLimit() {
return ruleBuilder.buildLimit();
}
}
3.7 K3Api,数据连接查询,这里将其注入Spring容器中,便于使用
@Component
public final class K3Api {
private final Logger log = LoggerFactory.getLogger(K3Api.class);
/**
* K3Cloud对象
*/
private final K3CloudApi api = new K3CloudApi();
/**
* 当次查询字段
*/
private List<String> fieldKeys;
/**
* 解析类上的注解FormId,获取表单Id
*
* @param cls
* @param
* @return 存在返回FormId,不存在返回空字符
*/
public <T> String getFormId(Class<T> cls) {
FormId formId = cls.getDeclaredAnnotation(FormId.class);
if (formId != null) {
return formId.value();
} else {
return "";
}
}
/**
* 获取字段的值
*
* @param filedName 字段名称
* @param obj 对象
* @return
*/
private final Object getFieldValue(String filedName, Object obj) {
try {
Class<?> objCls = obj.getClass();
String firstLetter = filedName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + filedName.substring(1);
Method method = objCls.getMethod(getter, new Class[]{});
Object value = method.invoke(obj, new Object[]{});
return value;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 设置字段的值
*
* @param filedName 字段名称
* @param value 字段值
* @param obj 对象
* @return
*/
private final void setFieldValue(String filedName, Object value, Object obj) {
try {
Class<?> objClass = obj.getClass();
Field field = objClass.getDeclaredField(filedName);
String firstLetter = filedName.substring(0, 1).toUpperCase();
String setter = "set" + firstLetter + filedName.substring(1);
Method method = objClass.getMethod(setter, field.getType());
// 日期格式如果值为字符换需要转换
if (field.getType() == Date.class && !(value instanceof Date)) {
// 对标准时间处理
String d = value.toString().replace("T", " ").replace("Z", "");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
method.invoke(obj, format.parse(d));
} else {
method.invoke(obj, value);
}
} catch (Exception e) {
}
}
/**
* 主要用于查询列表中主键对象是否封装
* 判断列表中是否包含某个子段元素
*
* @param list 查询列表
* @param fieldName 字段名
* @param value 值
* @param
* @return 返回该元素
*/
private final <T> T containObj(List<T> list, String fieldName, Object value) {
T t;
for (T item : list) {
Object oldValue = getFieldValue(fieldName, item);
// 字段相同,表示录入同一对象
if (oldValue.equals(value)) {
t = item;
return t;
}
}
return null;
}
/**
* 判断类中是否包含某个字段名
*
* @param clsMap
* @param fileName
* @return 返回包含字段名的类型
*/
private final String containClass(Map<String, Class> clsMap, String fileName) {
Set<Map.Entry<String, Class>> entries = clsMap.entrySet();
Iterator<Map.Entry<String, Class>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, Class> entry = iterator.next();
Field[] fields = entry.getValue().getDeclaredFields();
for (Field field : fields) {
if (field.getName().equals(fileName)) {
return entry.getKey();
}
}
}
return null;
}
/**
* 查询数据 : 此方法需要在cls上添加注解@FormId
* @param filter 类条件构建器
* @param
* @return List-T
*/
public <T> List<T> query(Builder<T> filter) {
Class<T> cls = filter.getObjClass();
String formId = getFormId(cls);
return query(formId, filter, cls);
}
/**
* 查询数据
*
* @param formId 查询表单ID
* @param filter 条件构建器
* @param cls 查询类
* @param
* @return List-T
*/
public <T> List<T> query(String formId, AbstractBuilder<T> filter, Class<T> cls) {
try {
// 保存当前查询字段
fieldKeys = filter.getFieldKeys();
QueryParam queryParam = new QueryParam();
queryParam.setFormId(formId);
queryParam.setFieldKeys(filter.buildFieldKeys());
queryParam.setFilterString(filter.buildFilter());
queryParam.setOrderString(filter.buildOrder());
queryParam.setTopRowCount(filter.buildTopRowCount());
queryParam.setStartRow(filter.buildStartRow());
queryParam.setLimit(filter.buildLimit());
// 打印日志
log.info("请求信息:{}", queryParam.toJson());
// 查询结果集
List<List<Object>> lists = api.executeBillQuery(queryParam.toJson());
// 封装结果集
List<T> resultList = new ArrayList<>();
lists.forEach(item -> {
try {
T result = cls.newInstance();
for (int i = 0; i < fieldKeys.size(); i++) {
// 将所有字段中.替换为_
String fieldName = fieldKeys.get(i).replace(".","_");
setFieldValue(fieldName, item.get(i), result);
}
resultList.add(result);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
});
return resultList;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 查询数据
*
* @param formId 查询表单ID
* @param fieldKeys 查询字段
* @param cls 封装类
* @param
* @return List-T
*/
public <T> List<T> query(String formId, List<String> fieldKeys, Class<T> cls) {
FilterRuleBuilder builder = new FilterRuleBuilder();
builder.select(fieldKeys);
return query(formId, builder, cls);
}
/**
* 查询数据 : 此方法需要在cls上添加注解@FormId
*
* @param fieldKeys 查询字段
* @param cls 封装类
* @param
* @return List-T
*/
public <T> List<T> query(List<String> fieldKeys, Class<T> cls) {
String formId = getFormId(cls);
FilterRuleBuilder builder = new FilterRuleBuilder();
builder.select(fieldKeys);
return query(formId, builder, cls);
}
/**
* 查询数据
*
* @param formId 查询表单ID
* @param filter 条件查询构造器
* @return List-List
public List<List<Object>> query(String formId, AbstractBuilder filter) {
try {
fieldKeys = filter.getFieldKeys();
QueryParam queryParam = new QueryParam();
queryParam.setFormId(formId).setFieldKeys(filter.buildFieldKeys());
queryParam.setFilterString(filter.buildFilter());
queryParam.setOrderString(filter.buildOrder());
queryParam.setTopRowCount(filter.buildTopRowCount());
queryParam.setLimit(filter.buildLimit());
queryParam.setStartRow(filter.buildStartRow());
// 打印日志
log.info("请求信息:{}", queryParam.toJson());
List<List<Object>> lists = api.executeBillQuery(queryParam.toJson());
return lists;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 查询数据
*
* @param formId 查询表单ID
* @param fieldKeys 查询字段
* @return List-Object
*/
public List<List<Object>> query(String formId, List<String> fieldKeys) {
FilterRuleBuilder builder = new FilterRuleBuilder();
builder.select(fieldKeys);
return query(formId, builder);
}
/**
* 查询一条数据
*
* @param formId
* @param filter 条件构建器
* @param
* @return 数据存在一条返回,不存在返回null,多条报错
*/
public <T> T queryOne(String formId, Builder<T> filter) {
Class<T> cls = filter.getObjClass();
List<T> query = query(formId, filter, cls);
int size = query.size();
if (size == 1) {
return query.get(0);
} else if (size == 0) {
return null;
} else {
throw new RuntimeException("查询一条记录,但发现" + query.size() + "条数据");
}
}
/**
* 查询一条数据
*
* @param filter
* @param
* @return 数据存在一条返回,不存在返回null,多条报错
*/
public <T> T queryOne(Builder<T> filter) {
// 获取查询类
Class<T> cls = filter.getObjClass();
String formId = getFormId(cls);
return queryOne(formId,filter);
}
/**
* 查询一条数据
*
* @param formId
* @param filter
* @return 数据存在一条返回,不存在返回null,多条报错
*/
public List<Object> queryOne(String formId, AbstractBuilder filter) {
List<List<Object>> query = query(formId, filter);
int size = query.size();
if (size == 1) {
return query.get(0);
} else if (size == 0) {
return null;
} else {
throw new RuntimeException("查询一条记录,但发现" + query.size() + "条数据");
}
}
/**
* 统计数量
* FilterRuleBuilder的查询字段不生效
*
* @param formId
* @return
*/
public Long count(String formId, AbstractBuilder filter) {
List<List<Object>> query = null;
try {
QueryParam queryParam = new QueryParam();
queryParam.setFormId(formId);
queryParam.setFieldKeys("count(1)");
if (filter != null) {
queryParam.setFilterString(filter.buildFilter());
}
query = api.executeBillQuery(queryParam.toJson());
} catch (Exception e) {
e.printStackTrace();
}
return Long.parseLong((String) query.get(0).get(0));
}
/**
* 统计数量
*
* @param formId
* @return
*/
public long count(String formId) {
return count(formId, null);
}
/**
* 结果映射: 除请求参数的属性外,其他字段自动映射
*
* @param result 结果集
* @param cls 映射对象
* @param fieldId 主键Id
* @param properties 映射对象中的映射字段,可以是对象或list,
* 但是list只能有一个,因为映射最小单元是list的单位
* @param 对象类型
* @return
*/
public <T> List<T> resultMap(List result, Class<T> cls, String fieldId, String... properties) {
List<T> returnResult = new ArrayList<>();
try {
// 对象子对象A集合
Map<String, Class> subObjFields = new HashMap<>();
// 对象的子列表对象集合
Map<String, Class> subListFields = new HashMap<>();
for (String property : properties) {
Field field = cls.getDeclaredField(property);
if (field.getType() == List.class) {// 列表先获取列表泛型的对象,然后获取对象的字段
// 获取列表中的泛型
Type genericType = field.getGenericType();
// 获取类型Class
if (genericType instanceof ParameterizedType) {
ParameterizedType typeCls = (ParameterizedType) genericType;
Class subGenericClass = (Class<?>) typeCls.getActualTypeArguments()[0];
subListFields.put(property, subGenericClass);
}
} else {// 对象直接获取对象的字段
Class subObjClass = cls.getDeclaredField(property).getType();
subObjFields.put(property, subObjClass);
}
}
int size = result.size();
// 封装结果
for (int i = 0; i < size; i++) {
Object obj = result.get(i);
// obj是一个对象,根据对象封装
if (obj instanceof List) {// 列表类型的操作
List list = (List) obj;
packByList(returnResult, list, cls, fieldId, subObjFields, subListFields);
} else {// 对象类型的操作
packByObject(returnResult, obj, cls, fieldId, subObjFields, subListFields);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return returnResult;
}
/**
* 结果映射: 除请求参数的属性外,其他字段自动映射
*
* @param result 结果集
* @param cls 映射对象
* @param fieldId 主键Id
* @param properties 映射对象中的映射字段,可以是对象或list,
* 但是list只能有一个,因为映射最小单元是list的单位
* @param 对象类型
* @return
*/
public <T, R> List<T> resultMap(List result, Class<T> cls, SFunction<T, R> fieldId, SFunction<T, R>... properties) {
return resultMap(result, cls, SFunctionParse.resolve(fieldId), SFunctionParse.resolves(properties));
}
/**
* 包装List结果集,通常指没有第一次包装对象
*
* @param returnResult 封装目标结果集
* @param list 封装源对象
* @param cls 目标对象
* @param fieldId 主键字段
* @param subObjFields 目标对象中的子对象 key: 属性名,value: 对象类
* @param subListFields 目标对象中的子列表,key: 属性名,value: 子列表中的Class类
* @param
* @return
* @throws IllegalAccessException
* @throws InstantiationException
*/
private <T> List<T> packByList(List<T> returnResult, List list, Class<T> cls, String fieldId,
Map<String, Class> subObjFields, Map<String, Class> subListFields) throws IllegalAccessException, InstantiationException {
// 字段个数
int size = list.size();
// 单元素对象
T t = null;
Object subObj;
// 子列表中对象
Object listObj = null;
// 子列表
List<Object> subList;
for (int j = 0; j < size; j++) {
// 字段名,将点替换为字段
String fieldName = fieldKeys.get(j).replace(".", "_");
// 字段值
Object value = list.get(j);
// 主键字段创建新对象
if (fieldName.equals(fieldId)) {// 主键字段赋值
// 获取对象或创建对象
t = containObj(returnResult, fieldName, value);
// 同时添加到
if (t == null) {
t = cls.newInstance();
setFieldValue(fieldName, value, t);
// 创建新的对象并添加到结果集
returnResult.add(t);
}
} else {
// 判断是否为子对象,返回子对象的属性名
String subFieldName = containClass(subObjFields, fieldName);
// 获取子对象Class
Class subCls = subObjFields.get(subFieldName);
// 不为空表示在子对象中
if (subFieldName != null) {
// 获取当前对象的子对象
subObj = getFieldValue(subFieldName, t);
// 子对象为空,创建子对象
if (subObj == null) {
subObj = subCls.newInstance();
}
// 赋值子对象属性
setFieldValue(fieldName, value, subObj);
// 赋值对象属性
setFieldValue(subFieldName, subObj, t);
} else {// 不为子对象判断是否为子
// 判断是否为子列表
String subListFieldName = containClass(subListFields, fieldName);
if (subListFieldName == null) {// 为空表示普通属性,自动封装
setFieldValue(fieldName, value, t);
} else {
// 查询对象是否包含子列表,不包含创建,包含赋值
subList = (List<Object>) getFieldValue(subListFieldName, t);
if (subList == null) {
// 并将列表添加在对象中
subList = new ArrayList<>();
setFieldValue(subListFieldName, subList, t);
}
// 列表中的子对象是否存在,不存在创建并添加在列表中
if (listObj == null) {
// 获取子列表中的对象Class
Class subListCls = subListFields.get(subListFieldName);
listObj = subListCls.newInstance();
// 添加到子列表中
subList.add(listObj);
}
// 给列表对象赋值属性
setFieldValue(fieldName, value, listObj);
}
}
// 给对象赋值,如果包装对象外也存在该属性,同样进行赋值
setFieldValue(fieldName, value, t);
}
}
return returnResult;
}
/**
* 根据对象包装结果集
*
* @param returnResult 封装目标结果集
* @param obj 包装源对象
* @param cls 目标Class
* @param fieldId 主键Id
* @param subObjFields 目标对象中的子对象 key: 属性名,value: 对象类
* @param subListFields 目标对象中的子列表,key: 属性名,value: 子列表中的Class类
* @param
* @return
* @throws IllegalAccessException
* @throws InstantiationException
*/
private <T> List<T> packByObject(List<T> returnResult, Object obj, Class<T> cls, String fieldId,
Map<String, Class> subObjFields, Map<String, Class> subListFields)
throws IllegalAccessException, InstantiationException {
Field[] resultFields = obj.getClass().getDeclaredFields();
// 单元素对象
T t = null;
Object subObj;
// 子列表中对象
Object listObj = null;
// 子列表
List<Object> subList;
for (int j = 0; j < resultFields.length; j++) {
Field field = resultFields[j];
// 字段名
String fieldName = field.getName();
// 字段值
Object value = getFieldValue(fieldName, obj);
// 主键字段创建新对象
if (fieldName.equals(fieldId)) {// 主键字段赋值
// 获取对象或创建对象
t = containObj(returnResult, fieldName, value);
// 同时添加到
if (t == null) {
t = cls.newInstance();
setFieldValue(fieldName, value, t);
// 创建新的对象并添加到结果集
returnResult.add(t);
}
} else {
// 判断是否为子对象,返回子对象的属性名
String subFieldName = containClass(subObjFields, fieldName);
// 获取子对象Class
Class subCls = subObjFields.get(subFieldName);
// 不为空表示在子对象中
if (subFieldName != null) {
// 获取当前对象的子对象
subObj = getFieldValue(subFieldName, t);
// 子对象为空,创建子对象
if (subObj == null) {
subObj = subCls.newInstance();
}
// 赋值子对象属性
setFieldValue(fieldName, value, subObj);
// 赋值对象属性
setFieldValue(subFieldName, subObj, t);
} else {// 不为子对象判断是否为子
// 判断是否为子列表
String subListFieldName = containClass(subListFields, fieldName);
if (subListFieldName == null) {// 为空表示普通属性,自动封装
setFieldValue(fieldName, value, t);
} else {
// 查询对象是否包含子列表,不包含创建,包含赋值
subList = (List<Object>) getFieldValue(subListFieldName, t);
if (subList == null) {
// 并将列表添加在对象中
subList = new ArrayList<>();
setFieldValue(subListFieldName, subList, t);
}
// 列表中的子对象是否存在,不存在创建并添加在列表中
if (listObj == null) {
// 获取子列表中的对象Class
Class subListCls = subListFields.get(subListFieldName);
listObj = subListCls.newInstance();
// 添加到子列表中
subList.add(listObj);
}
// 给列表对象赋值属性
setFieldValue(fieldName, value, listObj);
}
}
// 给对象赋值,如果包装对象外也存在该属性,同样进行赋值
setFieldValue(fieldName, value, t);
}
}
return returnResult;
}
}
使用示例: 提示: 实体类首字母必须小写
@Data
@NoArgsConstructor
@AllArgsConstructor
@FormId("BD_Customer")
public class Customer {
private long fCUSTID;
private String fNumber;
private String fName;
private String fShortName;
public static void main(String[] args) {
// 1. 原始方式
K3CloudApi api = new K3CloudApi();
List<Customer> datas;
try {
QueryParam queryParam = new QueryParam();
queryParam.setFormId("BD_Customer")
.setFieldKeys("fCUSTID,fNumber,fName,fCreateDate")
.setFilterString("fCUSTID <= '***'");
datas = api.executeBillQuery(queryParam, Customer.class);
datas.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}
// 2. 封装 FilterRuleBuilder后
K3Api k3Api = new K3Api();
FilterRuleBuilder builder = new FilterRuleBuilder();
builder.select("fCUSTID", "fNumber", "fName", "fCreateDate")
.le("fCUSTID", "***");
List<Customer> customers = k3Api.query("BD_Customer", builder, Customer.class);
customers.forEach(System.out::println);
// 3. 封装 Builder后
List<Customer> customers1 = k3Api.query(Builder.builder(Customer.class)
.select(Customer::getFCUSTID, Customer::getFName, Customer::getFCreateDate));
customers.forEach(System.out::println);
/**
* 4. k3Api还封装了queryOne,count方法。
* 5. query之后,数据可能需要映射,k3Api还封装了resultMap方法。
* resultMap的参数如下: 类比mybatis的结果映射
* @param result query的结果集
* @param cls 映射对象的类
* @param fieldId 对象主键Id
* @param properties 需要映射的字段,可以是对象或list,
* 但是list只能有一个,因为映射最小单元是list的单位
* 示例不介绍了。
*/
}
}