org.zodiac.mybatisplus.binding.binder.FieldListBinder Maven / Gradle / Ivy
package org.zodiac.mybatisplus.binding.binder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanWrapper;
import org.zodiac.commons.support.SpringContextHolder;
import org.zodiac.commons.util.BeanUtil;
import org.zodiac.commons.util.Colls;
import org.zodiac.commons.util.lang.Strings;
import org.zodiac.core.exception.IllegalUsageException;
import org.zodiac.mybatisplus.binding.annotation.BindFieldList;
import org.zodiac.mybatisplus.binding.binder.remote.RemoteBindingManager;
import org.zodiac.mybatisplus.binding.helper.ResultAssembler;
import org.zodiac.sdk.toolkit.util.lang.StrUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 关联字段绑定。
*
*/
public class FieldListBinder extends FieldBinder {
private static final Logger log = LoggerFactory.getLogger(FieldListBinder.class);
public FieldListBinder(BindFieldList annotation, List voList) {
super(annotation.entity(), voList);
if (StrUtil.isNotBlank(annotation.splitBy())) {
this.splitBy = annotation.splitBy();
}
if (StrUtil.isNotBlank(annotation.orderBy())) {
this.orderBy = annotation.orderBy();
}
}
@Override
public void bind() {
if (Colls.emptyColl(annoObjectList)) {
return;
}
if (Colls.emptyColl(refObjJoinCols)) {
throw new IllegalUsageException("调用错误:无法从condition中解析出字段关联.");
}
if (referencedGetterFieldNameList == null) {
throw new IllegalUsageException("调用错误:字段绑定必须指定字段field.");
}
Map valueEntityListMap = new HashMap<>();
if (middleTable == null) {
/*直接关联。*/
super.simplifySelectColumns();
super.buildQueryWrapperJoinOn();
/*查询条件为空时不进行查询。*/
if (queryWrapper.isEmptyOfNormal()) {
return;
}
/*处理orderBy,附加排序。*/
this.appendOrderBy(remoteBindDTO);
List entityList = null;
/*查询entity列表: List。*/
if (StrUtil.isBlank(this.module)) {
/*本地查询获取匹配结果的entityList。*/
entityList = getEntityList(queryWrapper);
} else {
/*远程调用获取。*/
entityList = RemoteBindingManager.fetchEntityList(module, remoteBindDTO, referencedEntityClass);
}
if (Colls.notEmptyColl(entityList)) {
valueEntityListMap = this.buildMatchKey2FieldListMap(entityList);
}
/*遍历list并赋值。*/
ResultAssembler.bindFieldListPropValue(super.getMatchedAnnoObjectList(), getAnnoObjJoinFlds(),
valueEntityListMap, annoObjectSetterPropNameList, referencedGetterFieldNameList, this.splitBy);
} else {
/*通过中间表关联。*/
if (refObjJoinCols.size() > 1) {
throw new IllegalUsageException(NOT_SUPPORT_MSG);
}
/*提取注解条件中指定的对应的列表。*/
Map trunkObjCol2ValuesMap = super.buildTrunkObjCol2ValuesMap();
/*处理中间表, 将结果转换成map。*/
Map middleTableResultMap = middleTable.executeOneToManyQuery(trunkObjCol2ValuesMap);
if (Colls.emptyMap(middleTableResultMap)) {
return;
}
super.simplifySelectColumns();
/*处理orderBy,附加排序。*/
this.appendOrderBy(remoteBindDTO);
/*收集查询结果values集合。*/
List entityIdList = extractIdValueFromMap(middleTableResultMap);
if (StrUtil.isNotBlank(this.splitBy)) {
Class> fieldType = refObjPropInfo.getFieldTypeByColumn(refObjJoinCols.get(0));
entityIdList = ResultAssembler.unpackValueList(entityIdList, this.splitBy, fieldType);
}
/*构建查询条件。*/
String refObjJoinOnCol = refObjJoinCols.get(0);
List entityList = null;
/*查询entity列表: List。*/
if (StrUtil.isBlank(this.module)) {
/*本地查询获取匹配结果的entityList。*/
queryWrapper.in(refObjJoinOnCol, entityIdList);
entityList = getEntityList(queryWrapper);
} else {
/*远程调用获取。*/
remoteBindDTO.setRefJoinCol(refObjJoinOnCol).setInConditionValues(entityIdList);
entityList = RemoteBindingManager.fetchEntityList(module, remoteBindDTO, referencedEntityClass);
}
if (Colls.emptyColl(entityList)) {
return;
}
String refObjJoinOnField = toRefObjField(refObjJoinOnCol);
/*转换entity列表为Map。*/
Map> entityMap = BeanUtil.convertToStringKeyObjectListMap(entityList, refObjJoinOnField);
for (Map.Entry entry : middleTableResultMap.entrySet()) {
/*List*/
List annoObjFKList = entry.getValue();
if (Colls.emptyColl(annoObjFKList)) {
continue;
}
List valueList = new ArrayList();
for (Object obj : annoObjFKList) {
String valStr = String.valueOf(obj);
List ent = entityMap.get(valStr);
if (ent != null) {
valueList.addAll(ent);
} else if (StrUtil.isNotBlank(splitBy) && valStr.contains(splitBy)) {
for (String key : valStr.split(splitBy)) {
ent = entityMap.get(key);
if (ent != null) {
valueList.addAll(ent);
}
}
}
}
valueEntityListMap.put(entry.getKey(), valueList);
}
/*遍历list并赋值。*/
bindPropValue(super.getMatchedAnnoObjectList(), middleTable.getTrunkObjColMapping(), valueEntityListMap);
}
}
/***
* 从对象集合提取某个属性值到list中
*
* @param fromList 来源列表
* @param trunkObjColMapping 映射关系
* @param valueMatchMap 匹配的列表
* @param 类型
*/
private void bindPropValue(List fromList, Map trunkObjColMapping,
Map valueMatchMap) {
if (Colls.emptyColl(fromList) || Colls.emptyMap(valueMatchMap)) {
return;
}
StringBuilder sb = new StringBuilder();
try {
for (E object : fromList) {
boolean appendComma = false;
sb.setLength(0);
for (Map.Entry entry : trunkObjColMapping.entrySet()) {
String getterField = toAnnoObjField(entry.getKey());
String fieldValue = BeanUtil.getStringProperty(object, getterField);
if (appendComma) {
sb.append(Strings.COMMA);
}
sb.append(fieldValue);
if (appendComma == false) {
appendComma = true;
}
}
/*查找匹配Key。*/
List entityList = valueMatchMap.get(sb.toString());
if (entityList != null) {
BeanWrapper beanWrapper = SpringContextHolder.getBeanWrapper(object);
for (int i = 0; i < annoObjectSetterPropNameList.size(); i++) {
List valObjList = BeanUtil.collectToList(entityList, referencedGetterFieldNameList.get(i));
beanWrapper.setPropertyValue(annoObjectSetterPropNameList.get(i), valObjList);
}
}
}
} catch (Exception e) {
log.warn("设置属性值异常", e);
}
}
/**
* 构建匹配key-entity目标的map。
*
* @param list 源列表
* @return 结果
*/
private Map buildMatchKey2FieldListMap(List list) {
Map key2TargetListMap = new HashMap<>(list.size());
StringBuilder sb = new StringBuilder();
for (T entity : list) {
sb.setLength(0);
for (int i = 0; i < refObjJoinCols.size(); i++) {
String refObjJoinOnCol = refObjJoinCols.get(i);
String fldValue = BeanUtil.getStringProperty(entity, toRefObjField(refObjJoinOnCol));
if (i > 0) {
sb.append(Strings.COMMA);
}
sb.append(fldValue);
}
String matchKey = sb.toString();
List entityList = key2TargetListMap.get(matchKey);
if (entityList == null) {
entityList = new ArrayList<>();
key2TargetListMap.put(matchKey, entityList);
}
entityList.add(entity);
}
sb.setLength(0);
return key2TargetListMap;
}
}