use of org.sagacity.sqltoy.config.model.TableCascadeModel in project sagacity-sqltoy by chenrenfei.
the class ResultUtils method hiberarchySet.
/**
* @TODO 将集合数据反射到java对象并建立层次关系
* @param sqlToyContext
* @param entityMeta
* @param columnFieldMap
* @param queryResultRows
* @param labelNames
* @param resultType
* @param cascadeModel
* @param hiberarchyClasses
* @param fieldsMap
* @return
* @throws Exception
*/
private static List hiberarchySet(SqlToyContext sqlToyContext, EntityMeta entityMeta, HashMap<String, String> columnFieldMap, List queryResultRows, String[] labelNames, Class resultType, List<TableCascadeModel> cascadeModel, Class[] hiberarchyClasses, Map<Class, IgnoreKeyCaseMap<String, String>> fieldsMap) throws Exception {
// 获得所有层次关系的分组字段
String[] groupFields = cascadeModel.get(0).getFields();
int groupSize = groupFields.length;
int[] colIndexs = new int[groupSize];
IgnoreKeyCaseMap<String, Integer> labelIndexs = new IgnoreKeyCaseMap<String, Integer>();
int index = 0;
for (String label : labelNames) {
labelIndexs.put(label.replace("_", ""), index);
index++;
}
for (int i = 0; i < groupSize; i++) {
if (labelIndexs.containsKey(groupFields[i])) {
colIndexs[i] = labelIndexs.get(groupFields[i]);
} else {
throw new DataAccessException("查询结果中未包含属性:" + groupFields[i] + " 对应的值!");
}
}
// 判断是否存在oneToMany
boolean hasOneToMany = false;
for (TableCascadeModel cascade : cascadeModel) {
if (cascade.getCascadeType() == 1) {
hasOneToMany = true;
break;
}
}
// 分组的master数据
List masterData;
LinkedHashMap<String, List> groupListMap = null;
Iterator<List> groupListIter;
// 存在oneToMany 则将数据进行分组
if (hasOneToMany) {
groupListMap = hashGroupList(queryResultRows, colIndexs);
// 提取每组的第一条数据作为master数据
groupListIter = groupListMap.values().iterator();
masterData = new ArrayList();
while (groupListIter.hasNext()) {
masterData.add(groupListIter.next().get(0));
}
} else {
masterData = queryResultRows;
}
// 构造主对象集合
List result = BeanUtil.reflectListToBean(sqlToyContext.getTypeHandler(), masterData, convertRealProps(wrapMapFields(labelNames, fieldsMap, resultType), columnFieldMap), resultType);
List<List> oneToOnes = new ArrayList();
List<String> oneToOneProps = new ArrayList<String>();
TableCascadeModel oneToMany = null;
int oneToManySize = 0;
for (TableCascadeModel cascade : cascadeModel) {
// oneToOne模式
if (cascade.getCascadeType() == 2) {
boolean hasCascade = false;
if (hiberarchyClasses != null) {
for (Class hiberarchyClass : hiberarchyClasses) {
if (hiberarchyClass.equals(cascade.getMappedType())) {
hasCascade = true;
break;
}
}
} else {
hasCascade = true;
}
// 将多个oneToOne的数据批量构造
if (hasCascade) {
// 主对象字段属性转化为级联对象属性
if (cascade.getMappedFields() != null && cascade.getMappedFields().length > 0) {
for (int i = 0; i < groupSize; i++) {
labelNames[colIndexs[i]] = cascade.getMappedFields()[i];
}
}
columnFieldMap = null;
if (entityMeta != null && sqlToyContext.isEntity(cascade.getMappedType())) {
columnFieldMap = sqlToyContext.getEntityMeta(cascade.getMappedType()).getColumnFieldMap();
}
List oneToOneList = BeanUtil.reflectListToBean(sqlToyContext.getTypeHandler(), masterData, convertRealProps(wrapMapFields(labelNames, fieldsMap, cascade.getMappedType()), columnFieldMap), cascade.getMappedType());
wrapResultTranslate(sqlToyContext, oneToOneList, cascade.getMappedType());
oneToOnes.add(oneToOneList);
oneToOneProps.add(cascade.getProperty());
}
} else // 只支持一个oneToMany
{
// 指定了级联对象
if (hiberarchyClasses != null) {
for (Class hiberarchyClass : hiberarchyClasses) {
if (hiberarchyClass.equals(cascade.getMappedType())) {
oneToMany = cascade;
break;
}
}
} else {
// 不指定则以第一个为准
if (oneToMany == null) {
oneToMany = cascade;
}
oneToManySize++;
}
}
}
if (oneToManySize > 1 && hiberarchyClasses == null) {
throw new IllegalArgumentException("返回依照层次结构结果时,存在多个oneToMany映射关系,必须要指明hiberarchyClasses!");
}
Object masterBean;
// 循环将oneToOne 的一一通过反射赋值到主对象属性上
if (!oneToOneProps.isEmpty()) {
int oneToOneSize = oneToOneProps.size();
for (int i = 0, n = result.size(); i < n; i++) {
masterBean = result.get(i);
for (int j = 0; j < oneToOneSize; j++) {
BeanUtil.setProperty(masterBean, oneToOneProps.get(j), oneToOnes.get(j).get(i));
}
}
}
// 处理oneToMany
if (oneToMany != null) {
// 变化级联子对象的属性
if (oneToMany.getMappedFields() != null && oneToMany.getMappedFields().length > 0) {
for (int i = 0; i < groupSize; i++) {
labelNames[colIndexs[i]] = oneToMany.getMappedFields()[i];
}
}
Class oneToManyClass = oneToMany.getMappedType();
columnFieldMap = null;
if (entityMeta != null && sqlToyContext.isEntity(oneToManyClass)) {
columnFieldMap = sqlToyContext.getEntityMeta(oneToManyClass).getColumnFieldMap();
}
List item;
String property = oneToMany.getProperty();
// 循环分组Map
groupListIter = groupListMap.values().iterator();
index = 0;
while (groupListIter.hasNext()) {
masterBean = result.get(index);
item = BeanUtil.reflectListToBean(sqlToyContext.getTypeHandler(), groupListIter.next(), convertRealProps(wrapMapFields(labelNames, fieldsMap, oneToManyClass), columnFieldMap), oneToManyClass);
// 处理类上@Translate注解进行缓存翻译
wrapResultTranslate(sqlToyContext, item, oneToManyClass);
// 将子对象集合写到主对象属性上
BeanUtil.setProperty(masterBean, property, item);
index++;
}
}
return result;
}
use of org.sagacity.sqltoy.config.model.TableCascadeModel in project sagacity-sqltoy by chenrenfei.
the class ResultUtils method wrapQueryResult.
/**
* @todo 根据查询结果的类型,构造相应对象集合(增加map形式的结果返回机制)
* @param sqlToyContext
* @param queryResultRows
* @param labelNames
* @param resultType
* @param changedCols
* @param humpMapLabel
* @param hiberarchy 返回结果是否按层次化对象封装
* @param hiberarchyClasses
* @return
* @throws Exception
*/
public static List wrapQueryResult(SqlToyContext sqlToyContext, List queryResultRows, String[] labelNames, Class resultType, boolean changedCols, boolean humpMapLabel, boolean hiberarchy, Class[] hiberarchyClasses, Map<Class, IgnoreKeyCaseMap<String, String>> fieldsMap) throws Exception {
// 类型为null就默认返回二维List
if (queryResultRows == null || queryResultRows.isEmpty() || resultType == null || resultType.equals(List.class) || resultType.equals(ArrayList.class) || resultType.equals(Collection.class) || BeanUtil.isBaseDataType(resultType)) {
return queryResultRows;
}
// 返回数组类型
if (Array.class.equals(resultType)) {
return CollectionUtil.innerListToArray(queryResultRows);
}
// 已经存在pivot、unpivot、列环比计算等
if (changedCols) {
logger.warn("查询中存在类似pivot、列同比环比计算导致结果'列'数不固定,因此不支持转map或VO对象!");
SqlExecuteStat.debug("映射结果类型错误", "查询中存在类似pivot、列同比环比计算导致结果'列'数不固定,因此不支持转map或VO对象!");
}
Class superClass = resultType.getSuperclass();
// 如果结果类型是hashMap
if (resultType.equals(HashMap.class) || resultType.equals(ConcurrentHashMap.class) || resultType.equals(Map.class) || resultType.equals(ConcurrentMap.class) || HashMap.class.equals(superClass) || LinkedHashMap.class.equals(superClass) || ConcurrentHashMap.class.equals(superClass) || Map.class.equals(superClass)) {
int width = labelNames.length;
String[] realLabel = labelNames;
// 驼峰处理
if (humpMapLabel) {
realLabel = humpFieldNames(labelNames, null);
}
List result = new ArrayList();
List rowList;
boolean isMap = resultType.equals(Map.class);
boolean isConMap = resultType.equals(ConcurrentMap.class);
for (int i = 0, n = queryResultRows.size(); i < n; i++) {
rowList = (List) queryResultRows.get(i);
Map rowMap;
if (isMap) {
rowMap = new HashMap();
} else if (isConMap) {
rowMap = new ConcurrentHashMap();
} else {
rowMap = (Map) resultType.getDeclaredConstructor().newInstance();
}
for (int j = 0; j < width; j++) {
rowMap.put(realLabel[j], rowList.get(j));
}
result.add(rowMap);
}
return result;
}
HashMap<String, String> columnFieldMap = null;
EntityMeta entityMeta = null;
if (sqlToyContext.isEntity(resultType)) {
entityMeta = sqlToyContext.getEntityMeta(resultType);
columnFieldMap = entityMeta.getColumnFieldMap();
}
boolean hasCascade = false;
List<TableCascadeModel> cascadeModel = null;
if (hiberarchy) {
if (entityMeta != null) {
cascadeModel = entityMeta.getCascadeModels();
} else {
cascadeModel = BeanUtil.getCascadeModels(resultType);
}
if (cascadeModel != null && !cascadeModel.isEmpty()) {
hasCascade = true;
}
}
List result = null;
// 非层次结构
if (!hasCascade) {
// 封装成VO对象形式
result = BeanUtil.reflectListToBean(sqlToyContext.getTypeHandler(), queryResultRows, convertRealProps(wrapMapFields(labelNames, fieldsMap, resultType), columnFieldMap), resultType);
// update 2021-11-16 支持VO或POJO 属性上@Translate注解,进行缓存翻译
wrapResultTranslate(sqlToyContext, result, resultType);
} else {
result = hiberarchySet(sqlToyContext, entityMeta, columnFieldMap, queryResultRows, labelNames, resultType, cascadeModel, hiberarchyClasses, fieldsMap);
}
return result;
}
Aggregations