Search in sources :

Example 36 with DataAccessException

use of org.sagacity.sqltoy.exception.DataAccessException 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 37 with DataAccessException

use of org.sagacity.sqltoy.exception.DataAccessException in project sagacity-sqltoy by chenrenfei.

the class ResultUtils method getMoreLinkResultSet.

/**
 * @TODO 实现多列link
 * @param sqlToyConfig
 * @param sqlToyContext
 * @param decryptHandler
 * @param conn
 * @param rs
 * @param rowCnt
 * @param labelIndexMap
 * @param labelNames
 * @param startColIndex
 * @return
 * @throws Exception
 */
private static List getMoreLinkResultSet(SqlToyConfig sqlToyConfig, SqlToyContext sqlToyContext, DecryptHandler decryptHandler, Connection conn, ResultSet rs, int rowCnt, HashMap<String, Integer> labelIndexMap, String[] labelNames, int startColIndex) throws Exception {
    // 字段连接(多行数据拼接成一个数据,以一行显示)
    LinkModel linkModel = sqlToyConfig.getLinkModel();
    List<List> items = new ArrayList();
    // 判断是否有缓存翻译器定义
    Boolean hasTranslate = (sqlToyConfig.getTranslateMap().isEmpty()) ? false : true;
    HashMap<String, Translate> translateMap = sqlToyConfig.getTranslateMap();
    HashMap<String, HashMap<String, Object[]>> translateCache = null;
    if (hasTranslate) {
        translateCache = sqlToyContext.getTranslateManager().getTranslates(translateMap);
        if (translateCache == null || translateCache.isEmpty()) {
            hasTranslate = false;
            logger.debug("通过缓存配置未获取到缓存数据,请正确配置TranslateManager!");
        }
    }
    // link 目前只支持单个字段运算
    int columnSize = labelNames.length;
    int index = 0;
    // 警告阀值
    int warnThresholds = SqlToyConstants.getWarnThresholds();
    boolean warnLimit = false;
    // 最大阀值
    long maxThresholds = SqlToyConstants.getMaxThresholds();
    boolean maxLimit = false;
    // 是否判断全部为null的行记录
    boolean ignoreAllEmpty = sqlToyConfig.isIgnoreEmpty();
    // 最大值要大于等于警告阀值
    if (maxThresholds > 1 && maxThresholds <= warnThresholds) {
        maxThresholds = warnThresholds;
    }
    int linkCols = linkModel.getColumns().length;
    String[] linkColumns = linkModel.getColumns();
    int[] linkIndexs = new int[linkCols];
    StringBuilder[] linkBuffers = new StringBuilder[linkCols];
    Set<String>[] linkSets = linkModel.isDistinct() ? new HashSet[linkCols] : null;
    boolean[] translateLinks = new boolean[linkCols];
    TranslateExtend[] transExtends = new TranslateExtend[linkCols];
    String linkColumnLow;
    for (int i = 0; i < linkCols; i++) {
        linkBuffers[i] = new StringBuilder();
        linkColumnLow = linkColumns[i].toLowerCase();
        if (!labelIndexMap.containsKey(linkColumnLow)) {
            throw new DataAccessException("做link操作时,查询结果字段中没有字段:" + linkColumnLow + ",请检查sql或link 配置的正确性!");
        }
        linkIndexs[i] = labelIndexMap.get(linkColumnLow);
        if (hasTranslate) {
            translateLinks[i] = translateMap.containsKey(linkColumnLow);
            if (translateLinks[i]) {
                transExtends[i] = translateMap.get(linkColumnLow).getExtend();
            }
        }
        if (linkModel.isDistinct()) {
            linkSets[i] = new HashSet<String>();
        }
    }
    // link是否有修饰器
    boolean hasDecorate = (linkModel.getDecorateAppendChar() == null) ? false : true;
    boolean isLeft = true;
    if (hasDecorate) {
        isLeft = linkModel.getDecorateAlign().equals("left") ? true : false;
    }
    Object preIdentity = null;
    Object[] linkValues = new Object[linkCols];
    String[] linkStrs = new String[linkCols];
    TranslateExtend extend = null;
    Object[] cacheValues;
    List rowTemp;
    Object identity = null;
    // 判断link拼接是否重新开始
    boolean isLastProcess = false;
    boolean doLink = false;
    while (rs.next()) {
        isLastProcess = false;
        // 对多个link字段取值并进行翻译转义
        for (int i = 0; i < linkCols; i++) {
            linkValues[i] = rs.getObject(linkColumns[i]);
            if (linkValues[i] == null) {
                linkStrs[i] = "";
            } else {
                if (translateLinks[i]) {
                    extend = transExtends[i];
                    cacheValues = translateCache.get(extend.column).get(linkValues[i].toString());
                    if (cacheValues == null) {
                        linkStrs[i] = "[" + linkValues[i] + "]未匹配";
                        logger.debug("translate cache:{},cacheType:{}, 对应的key:{} 没有设置相应的value!", extend.cache, extend.cacheType, linkValues[i]);
                    } else {
                        linkStrs[i] = (cacheValues[extend.index] == null) ? "" : cacheValues[extend.index].toString();
                    }
                } else {
                    linkStrs[i] = linkValues[i].toString();
                }
            }
        }
        // 取分组列的值
        identity = (linkModel.getIdColumns() == null) ? "default" : getLinkColumnsId(rs, linkModel.getIdColumns());
        // 不相等
        if (!identity.equals(preIdentity)) {
            // 不相等时先对最后一条记录修改,写入拼接后的字符串
            if (index != 0) {
                rowTemp = items.get(items.size() - 1);
                for (int i = 0; i < linkCols; i++) {
                    rowTemp.set(linkIndexs[i], linkBuffers[i].toString());
                    linkBuffers[i].delete(0, linkBuffers[i].length());
                    // 清除
                    if (linkModel.isDistinct()) {
                        linkSets[i].clear();
                    }
                }
            }
            // 再写入新的拼接串
            for (int i = 0; i < linkCols; i++) {
                linkBuffers[i].append(linkStrs[i]);
                if (linkModel.isDistinct()) {
                    linkSets[i].add(linkStrs[i]);
                }
            }
            // 提取result中的数据(identity相等时不需要提取)
            if (hasTranslate) {
                rowTemp = processResultRowWithTranslate(translateMap, translateCache, labelNames, rs, columnSize, decryptHandler, ignoreAllEmpty);
            } else {
                rowTemp = processResultRow(rs, labelNames, columnSize, decryptHandler, ignoreAllEmpty);
            }
            if (rowTemp != null) {
                items.add(rowTemp);
            }
            preIdentity = identity;
        } else {
            isLastProcess = true;
            // identity相同,表示还在同一组内,直接拼接link字符
            for (int i = 0; i < linkCols; i++) {
                doLink = true;
                // 判断是否已经重复
                if (linkModel.isDistinct()) {
                    if (linkSets[i].contains(linkStrs[i])) {
                        doLink = false;
                    }
                    linkSets[i].add(linkStrs[i]);
                }
                if (doLink) {
                    if (linkBuffers[i].length() > 0) {
                        linkBuffers[i].append(linkModel.getSign());
                    }
                    linkBuffers[i].append(hasDecorate ? StringUtil.appendStr(linkStrs[i], linkModel.getDecorateAppendChar(), linkModel.getDecorateSize(), isLeft) : linkStrs[i]);
                }
            }
        }
        index++;
        // 存在超出25000条数据的查询
        if (index == warnThresholds) {
            warnLimit = true;
        }
        // 提取数据超过上限(-1表示不限制)
        if (index == maxThresholds) {
            maxLimit = true;
            break;
        }
    }
    // 数据集合不为空,对最后一条记录写入循环值
    if (isLastProcess) {
        rowTemp = items.get(items.size() - 1);
        for (int i = 0; i < linkCols; i++) {
            rowTemp.set(linkIndexs[i], linkBuffers[i].toString());
        }
    }
    // 超出警告阀值
    if (warnLimit) {
        warnLog(sqlToyConfig, index);
    }
    // 超过最大提取数据阀值
    if (maxLimit) {
        logger.error("MaxLargeResult:执行sql提取数据超出最大阀值限制{},sqlId={},具体语句={}", index, sqlToyConfig.getId(), sqlToyConfig.getSql(null));
    }
    return items;
}
Also used : ResultSet(java.sql.ResultSet) Set(java.util.Set) HashSet(java.util.HashSet) IgnoreCaseSet(org.sagacity.sqltoy.model.IgnoreCaseSet) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) LinkModel(org.sagacity.sqltoy.config.model.LinkModel) ReverseList(org.sagacity.sqltoy.plugins.calculator.ReverseList) List(java.util.List) ArrayList(java.util.ArrayList) UnpivotList(org.sagacity.sqltoy.plugins.calculator.UnpivotList) Translate(org.sagacity.sqltoy.config.model.Translate) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) TranslateExtend(org.sagacity.sqltoy.model.inner.TranslateExtend)

Example 38 with DataAccessException

use of org.sagacity.sqltoy.exception.DataAccessException in project sagacity-sqltoy by chenrenfei.

the class Mongo method findTop.

/**
 * @todo 查询前多少条记录
 * @param topSize
 * @return
 */
public List<?> findTop(final Float topSize) {
    QueryExecutor queryExecutor = build();
    SqlToyConfig sqlToyConfig = sqlToyContext.getSqlToyConfig(sql, SqlType.search, "");
    NoSqlConfigModel noSqlModel = sqlToyConfig.getNoSqlConfigModel();
    if (noSqlModel == null || noSqlModel.getCollection() == null || noSqlModel.getFields() == null) {
        throw new IllegalArgumentException(ERROR_MESSAGE);
    }
    try {
        QueryExecutorExtend extend = queryExecutor.getInnerModel();
        // 最后的执行语句
        String realMql = MongoElasticUtils.wrapMql(sqlToyConfig, extend.getParamsName(sqlToyConfig), extend.getParamsValue(sqlToyContext, sqlToyConfig));
        return findTop(getMongoTemplate(), sqlToyConfig, topSize, realMql, (Class) extend.resultType, extend.humpMapLabel);
    } catch (Exception e) {
        e.printStackTrace();
        throw new DataAccessException(e);
    }
}
Also used : NoSqlConfigModel(org.sagacity.sqltoy.config.model.NoSqlConfigModel) QueryExecutor(org.sagacity.sqltoy.model.QueryExecutor) SqlToyConfig(org.sagacity.sqltoy.config.model.SqlToyConfig) QueryExecutorExtend(org.sagacity.sqltoy.model.inner.QueryExecutorExtend) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 39 with DataAccessException

use of org.sagacity.sqltoy.exception.DataAccessException in project sagacity-sqltoy by chenrenfei.

the class Mongo method findPage.

/**
 * @todo 分页查询
 * @param page
 * @return
 */
public Page findPage(Page page) {
    QueryExecutor queryExecutor = build();
    SqlToyConfig sqlToyConfig = sqlToyContext.getSqlToyConfig(sql, SqlType.search, "");
    NoSqlConfigModel noSqlModel = sqlToyConfig.getNoSqlConfigModel();
    if (noSqlModel == null || noSqlModel.getCollection() == null || noSqlModel.getFields() == null) {
        throw new IllegalArgumentException(ERROR_MESSAGE);
    }
    try {
        QueryExecutorExtend extend = queryExecutor.getInnerModel();
        // 最后的执行语句
        String realMql = MongoElasticUtils.wrapMql(sqlToyConfig, extend.getParamsName(sqlToyConfig), extend.getParamsValue(sqlToyContext, sqlToyConfig));
        return findPage(getMongoTemplate(), sqlToyConfig, page, realMql, (Class) extend.resultType, extend.humpMapLabel);
    } catch (Exception e) {
        e.printStackTrace();
        throw new DataAccessException(e);
    }
}
Also used : NoSqlConfigModel(org.sagacity.sqltoy.config.model.NoSqlConfigModel) QueryExecutor(org.sagacity.sqltoy.model.QueryExecutor) SqlToyConfig(org.sagacity.sqltoy.config.model.SqlToyConfig) QueryExecutorExtend(org.sagacity.sqltoy.model.inner.QueryExecutorExtend) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 40 with DataAccessException

use of org.sagacity.sqltoy.exception.DataAccessException in project sagacity-sqltoy by chenrenfei.

the class SqlScriptLoader method getSqlConfig.

/**
 * @todo 提供根据sql或sqlId获取sql配置模型
 * @param sqlKey
 * @param sqlType
 * @param dialect
 * @return
 */
public SqlToyConfig getSqlConfig(String sqlKey, SqlType sqlType, String dialect) {
    if (StringUtil.isBlank(sqlKey)) {
        throw new IllegalArgumentException("sql or sqlId is null!");
    }
    SqlToyConfig result = null;
    String realDialect = (dialect == null) ? "" : dialect.toLowerCase();
    // sqlId形式
    if (SqlConfigParseUtils.isNamedQuery(sqlKey)) {
        if (!realDialect.equals("")) {
            // sqlId_dialect
            result = sqlCache.get(sqlKey.concat("_").concat(realDialect));
            // dialect_sqlId
            if (result == null) {
                result = sqlCache.get(realDialect.concat("_").concat(sqlKey));
            }
            // 兼容一下sqlserver的命名
            if (result == null && realDialect.equals(Dialect.SQLSERVER)) {
                result = sqlCache.get(sqlKey.concat("_mssql"));
                if (result == null) {
                    result = sqlCache.get("mssql_".concat(sqlKey));
                }
            }
            // 兼容一下postgres的命名
            if (result == null && realDialect.equals(Dialect.POSTGRESQL)) {
                result = sqlCache.get(sqlKey.concat("_postgres"));
                if (result == null) {
                    result = sqlCache.get("postgres_".concat(sqlKey));
                }
            }
        }
        if (result == null) {
            result = sqlCache.get(sqlKey);
            if (result == null) {
                throw new DataAccessException("\n发生错误:sqlId=[" + sqlKey + "]无对应的sql配置,请检查对应的sql.xml文件是否被正确加载!\n" + "/*----------------------错误可能的原因如下---------------------*/\n" + "/* 1、检查: spring.sqltoy.sqlResourcesDir=[" + sqlResourcesDir + "]配置(如:字母拼写),会导致sql文件没有被加载;\n" + "/* 2、sql.xml文件没有被编译到classes目录下面;请检查maven的编译配置                        \n" + "/* 3、sqlId对应的文件内部错误!版本合并或书写错误会导致单个文件解析错误                          \n" + "/* ------------------------------------------------------------*/");
            }
        }
    } else {
        result = codeSqlCache.get(sqlKey);
        if (result == null) {
            result = SqlConfigParseUtils.parseSqlToyConfig(sqlKey, realDialect, sqlType);
            // 设置默认空白查询条件过滤filter,便于直接传递sql语句情况下查询条件的处理
            result.addFilter(new ParamFilterModel("blank", new String[] { "*" }));
            // 限制数量的原因是存在部分代码中的sql会拼接条件参数值,导致不同的sql无限增加
            if (codeSqlCache.size() < SqlToyConstants.getMaxCodeSqlCount()) {
                codeSqlCache.put(sqlKey, result);
            }
        }
    }
    return result;
}
Also used : SqlToyConfig(org.sagacity.sqltoy.config.model.SqlToyConfig) ParamFilterModel(org.sagacity.sqltoy.config.model.ParamFilterModel) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Aggregations

DataAccessException (org.sagacity.sqltoy.exception.DataAccessException)40 Connection (java.sql.Connection)24 DataSourceCallbackHandler (org.sagacity.sqltoy.callback.DataSourceCallbackHandler)24 ArrayList (java.util.ArrayList)19 SqlToyConfig (org.sagacity.sqltoy.config.model.SqlToyConfig)17 List (java.util.List)13 ShardingModel (org.sagacity.sqltoy.config.model.ShardingModel)13 QueryExecutorExtend (org.sagacity.sqltoy.model.inner.QueryExecutorExtend)12 QueryExecutor (org.sagacity.sqltoy.model.QueryExecutor)9 QueryResult (org.sagacity.sqltoy.model.QueryResult)9 SqlToyResult (org.sagacity.sqltoy.config.model.SqlToyResult)6 HashMap (java.util.HashMap)5 Serializable (java.io.Serializable)4 NoSqlConfigModel (org.sagacity.sqltoy.config.model.NoSqlConfigModel)4 HashSet (java.util.HashSet)3 ExecutorService (java.util.concurrent.ExecutorService)3 EntityMeta (org.sagacity.sqltoy.config.model.EntityMeta)3 FieldMeta (org.sagacity.sqltoy.config.model.FieldMeta)3 Type (java.lang.reflect.Type)2 ResultSet (java.sql.ResultSet)2