use of com.diboot.core.binding.query.dynamic.DynamicJoinQueryWrapper in project diboot by dibo-software.
the class JoinsBinder method executeJoinQuery.
/**
* 关联查询(分页)
* @param queryWrapper 调用QueryBuilder.to*QueryWrapper得到的实例
* @param entityClazz 返回结果entity/vo类
* @param pagination 分页
* @return
* @throws Exception
*/
private static <DTO, E> List<E> executeJoinQuery(QueryWrapper<DTO> queryWrapper, Class<E> entityClazz, Pagination pagination, boolean limit1) {
// 非动态查询,走BaseService
if (queryWrapper instanceof DynamicJoinQueryWrapper == false) {
IService iService = ContextHelper.getIServiceByEntity(entityClazz);
if (iService != null) {
return ServiceAdaptor.queryList(iService, (QueryWrapper) queryWrapper, pagination, entityClazz);
} else {
throw new InvalidUsageException("单表查询对象无BaseService/IService实现: " + entityClazz.getSimpleName());
}
}
long begin = System.currentTimeMillis();
// 转换为queryWrapper
DynamicJoinQueryWrapper dynamicJoinWrapper = (DynamicJoinQueryWrapper) queryWrapper;
dynamicJoinWrapper.setMainEntityClass(entityClazz);
List<Map<String, Object>> mapList = null;
if (pagination == null) {
if (limit1) {
Page page = new Page<>(1, 1);
page.setSearchCount(false);
IPage<Map<String, Object>> pageResult = getDynamicQueryMapper().queryForListWithPage(page, dynamicJoinWrapper);
mapList = pageResult.getRecords();
} else {
mapList = getDynamicQueryMapper().queryForList(dynamicJoinWrapper);
}
} else {
// 格式化orderBy
formatOrderBy(dynamicJoinWrapper, entityClazz, pagination);
IPage<Map<String, Object>> pageResult = getDynamicQueryMapper().queryForListWithPage(pagination.toPage(), dynamicJoinWrapper);
pagination.setTotalCount(pageResult.getTotal());
mapList = pageResult.getRecords();
}
long ms = (System.currentTimeMillis() - begin);
if (ms > 5000) {
log.warn("{} 动态Join查询执行耗时 {} ms,建议优化", dynamicJoinWrapper.getDtoClass().getSimpleName(), ms);
}
if (V.isEmpty(mapList)) {
return Collections.emptyList();
}
if (mapList.size() > BaseConfig.getBatchSize()) {
log.warn("{} 动态Join查询记录数过大( {} 条), 建议优化", dynamicJoinWrapper.getDtoClass().getSimpleName(), mapList.size());
}
// 转换查询结果
List<E> entityList = new ArrayList<>();
for (Map<String, Object> colValueMap : mapList) {
Map<String, Object> fieldValueMap = new HashMap<>();
// 格式化map
for (Map.Entry<String, Object> entry : colValueMap.entrySet()) {
String fieldName = S.toLowerCaseCamel(entry.getKey());
// 如果是布尔类型,检查entity中的定义是Boolean/boolean
if (entry.getValue() instanceof Boolean && S.startsWithIgnoreCase(entry.getKey(), "is_")) {
// 检查有is前缀的Boolean类型
Field boolType = BeanUtils.extractField(entityClazz, fieldName);
if (boolType == null) {
// 检查无is前缀的boolean类型
String tempFieldName = S.toLowerCaseCamel(S.substringAfter(entry.getKey(), "_"));
boolType = BeanUtils.extractField(entityClazz, tempFieldName);
if (boolType != null) {
fieldName = tempFieldName;
}
}
}
fieldValueMap.put(fieldName, entry.getValue());
}
// 绑定map到entity
try {
E entityInst = entityClazz.newInstance();
BeanUtils.bindProperties(entityInst, fieldValueMap);
if (ENABLE_DATA_PROTECT) {
ParserCache.getFieldEncryptorMap(entityClazz).forEach((k, v) -> {
String value = BeanUtils.getStringProperty(entityInst, k);
BeanUtils.setProperty(entityInst, k, value == null ? null : v.decrypt(value));
});
}
entityList.add(entityInst);
} catch (Exception e) {
log.warn("new实例并绑定属性值异常", e);
}
}
return entityList;
}
use of com.diboot.core.binding.query.dynamic.DynamicJoinQueryWrapper in project diboot by dibo-software.
the class QueryBuilder method dtoToWrapper.
/**
* 转换具体实现
*
* @param dto
* @return
*/
private static <DTO> QueryWrapper<?> dtoToWrapper(DTO dto, Collection<String> fields) {
QueryWrapper<?> wrapper;
// 转换
LinkedHashMap<String, FieldAndValue> fieldValuesMap = extractNotNullValues(dto, fields);
if (V.isEmpty(fieldValuesMap)) {
return new QueryWrapper<>();
}
// 只解析有值的
fields = fieldValuesMap.keySet();
// 是否有join联表查询
boolean hasJoinTable = ParserCache.hasJoinTable(dto, fields);
if (hasJoinTable) {
wrapper = new DynamicJoinQueryWrapper<>(dto.getClass(), fields);
} else {
wrapper = new ExtQueryWrapper<>();
}
// 构建 ColumnName
List<AnnoJoiner> annoJoinerList = ParserCache.getBindQueryAnnos(dto.getClass());
BiFunction<BindQuery, Field, String> buildColumnName = (bindQuery, field) -> {
if (bindQuery != null) {
String key = field.getName() + bindQuery;
for (AnnoJoiner annoJoiner : annoJoinerList) {
if (key.equals(annoJoiner.getKey())) {
if (V.notEmpty(annoJoiner.getJoin())) {
// 获取注解Table
return annoJoiner.getAlias() + "." + annoJoiner.getColumnName();
} else {
return (hasJoinTable ? "self." : "") + annoJoiner.getColumnName();
}
}
}
}
return (hasJoinTable ? "self." : "") + BeanUtils.getColumnName(field);
};
// 忽略空字符串"",空集合等
BiFunction<Object, BindQuery, Boolean> ignoreEmpty = (value, bindQuery) -> bindQuery != null && // 忽略空字符串"",空集合等
bindQuery.strategy().equals(Strategy.IGNORE_EMPTY) && (// 字符串""
value instanceof String && S.isEmpty((String) value) || // 空集合
(value instanceof Collection && ((Collection<?>) value).size() == 0));
// 查找加密策略
BiFunction<BindQuery, String, IEncryptStrategy> findEncryptStrategy = (bindQuery, defFieldName) -> {
if (ENABLE_DATA_PROTECT) {
Class<?> clazz = bindQuery == null || bindQuery.entity() == NullType.class ? dto.getClass() : bindQuery.entity();
String fieldName = bindQuery == null || S.isEmpty(bindQuery.field()) ? defFieldName : bindQuery.field();
return ParserCache.getFieldEncryptorMap(clazz).get(fieldName);
}
return null;
};
// 构建QueryWrapper
for (Map.Entry<String, FieldAndValue> entry : fieldValuesMap.entrySet()) {
FieldAndValue fieldAndValue = entry.getValue();
Field field = fieldAndValue.getField();
// 忽略注解 @TableField(exist = false) 的字段
TableField tableField = field.getAnnotation(TableField.class);
if (tableField != null && !tableField.exist()) {
continue;
}
// 忽略字段
BindQuery query = field.getAnnotation(BindQuery.class);
if (query != null && query.ignore()) {
continue;
}
BindQuery.List queryList = field.getAnnotation(BindQuery.List.class);
Object value = fieldAndValue.getValue();
// 构建Query
if (queryList != null) {
wrapper.and(queryWrapper -> {
for (BindQuery bindQuery : queryList.value()) {
if (ignoreEmpty.apply(value, bindQuery)) {
continue;
}
IEncryptStrategy encryptor = findEncryptStrategy.apply(bindQuery, entry.getKey());
Comparison comparison = encryptor == null ? bindQuery.comparison() : Comparison.EQ;
String columnName = buildColumnName.apply(bindQuery, field);
buildQuery(queryWrapper.or(), comparison, columnName, encryptor == null ? value : encryptor.encrypt(value.toString()));
}
});
} else {
if (ignoreEmpty.apply(value, query)) {
continue;
}
IEncryptStrategy encryptor = findEncryptStrategy.apply(query, entry.getKey());
Comparison comparison = query != null && encryptor == null ? query.comparison() : Comparison.EQ;
String columnName = buildColumnName.apply(query, field);
buildQuery(wrapper, comparison, columnName, encryptor == null ? value : encryptor.encrypt(value.toString()));
}
}
return wrapper;
}
Aggregations