Search in sources :

Example 11 with TableCascadeModel

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;
}
Also used : ArrayList(java.util.ArrayList) TableCascadeModel(org.sagacity.sqltoy.config.model.TableCascadeModel) IgnoreKeyCaseMap(org.sagacity.sqltoy.model.IgnoreKeyCaseMap) ReverseList(org.sagacity.sqltoy.plugins.calculator.ReverseList) List(java.util.List) ArrayList(java.util.ArrayList) UnpivotList(org.sagacity.sqltoy.plugins.calculator.UnpivotList) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 12 with TableCascadeModel

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;
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) ConcurrentMap(java.util.concurrent.ConcurrentMap) TableCascadeModel(org.sagacity.sqltoy.config.model.TableCascadeModel) LinkedHashMap(java.util.LinkedHashMap) ReverseList(org.sagacity.sqltoy.plugins.calculator.ReverseList) List(java.util.List) ArrayList(java.util.ArrayList) UnpivotList(org.sagacity.sqltoy.plugins.calculator.UnpivotList) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) LinkedHashMap(java.util.LinkedHashMap) IgnoreKeyCaseMap(org.sagacity.sqltoy.model.IgnoreKeyCaseMap)

Aggregations

TableCascadeModel (org.sagacity.sqltoy.config.model.TableCascadeModel)12 EntityMeta (org.sagacity.sqltoy.config.model.EntityMeta)10 ArrayList (java.util.ArrayList)8 List (java.util.List)8 ReflectPropsHandler (org.sagacity.sqltoy.callback.ReflectPropsHandler)4 SqlToyResult (org.sagacity.sqltoy.config.model.SqlToyResult)4 HashMap (java.util.HashMap)3 IOException (java.io.IOException)2 Type (java.lang.reflect.Type)2 PreparedStatement (java.sql.PreparedStatement)2 ResultSet (java.sql.ResultSet)2 SQLException (java.sql.SQLException)2 DecryptHandler (org.sagacity.sqltoy.callback.DecryptHandler)2 PreparedStatementResultHandler (org.sagacity.sqltoy.callback.PreparedStatementResultHandler)2 OneToMany (org.sagacity.sqltoy.config.annotation.OneToMany)2 OneToOne (org.sagacity.sqltoy.config.annotation.OneToOne)2 IgnoreKeyCaseMap (org.sagacity.sqltoy.model.IgnoreKeyCaseMap)2 ReverseList (org.sagacity.sqltoy.plugins.calculator.ReverseList)2 UnpivotList (org.sagacity.sqltoy.plugins.calculator.UnpivotList)2 DBType (org.sagacity.sqltoy.utils.DataSourceUtils.DBType)2