Search in sources :

Example 1 with DecryptHandler

use of org.sagacity.sqltoy.callback.DecryptHandler in project sagacity-sqltoy by chenrenfei.

the class DialectUtils method loadAll.

/**
 * @todo 提供统一的loadAll处理机制
 * @param sqlToyContext
 * @param entities
 * @param cascadeTypes
 * @param lockMode
 * @param conn
 * @param dbType
 * @param tableName
 * @param lockSqlHandler
 * @param fetchSize
 * @param maxRows
 * @return
 * @throws Exception
 */
public static List<?> loadAll(final SqlToyContext sqlToyContext, List<?> entities, List<Class> cascadeTypes, LockMode lockMode, Connection conn, final Integer dbType, String tableName, LockSqlHandler lockSqlHandler, final int fetchSize, final int maxRows) throws Exception {
    if (entities == null || entities.isEmpty()) {
        return entities;
    }
    Class entityClass = BeanUtil.getEntityClass(entities.get(0).getClass());
    EntityMeta entityMeta = sqlToyContext.getEntityMeta(entityClass);
    // 没有主键不能进行load相关的查询
    if (null == entityMeta.getIdArray() || entityMeta.getIdArray().length < 1) {
        throw new IllegalArgumentException(entityClass.getName() + " Entity Object hasn't primary key,cann't use loadAll method!");
    }
    DecryptHandler decryptHandler = null;
    if (entityMeta.getSecureColumns() != null) {
        decryptHandler = new DecryptHandler(sqlToyContext.getFieldsSecureProvider(), entityMeta.getSecureColumns());
    }
    int idSize = entityMeta.getIdArray().length;
    SqlToyResult sqlToyResult = null;
    // 单主键
    if (idSize == 1) {
        // 切取id数组
        Object[] idValues = BeanUtil.sliceToArray(entities, entityMeta.getIdArray()[0]);
        if (idValues == null || idValues.length == 0) {
            throw new IllegalArgumentException(tableName + " loadAll method must assign value for pk field:" + entityMeta.getIdArray()[0]);
        }
        // 组织loadAll sql语句
        String sql = wrapLoadAll(entityMeta, idValues.length, tableName, lockSqlHandler, lockMode, dbType);
        sqlToyResult = SqlConfigParseUtils.processSql(sql, null, new Object[] { idValues }, null);
    } else // 复合主键
    {
        List<Object[]> idValues = BeanUtil.reflectBeansToInnerAry(entities, entityMeta.getIdArray(), null, null);
        Object[] rowData;
        Object cellValue;
        // 将条件构造成一个数组
        Object[] realValues = new Object[idValues.size() * idSize];
        int index = 0;
        for (int i = 0, n = idValues.size(); i < n; i++) {
            rowData = idValues.get(i);
            for (int j = 0; j < idSize; j++) {
                cellValue = rowData[j];
                // 验证主键值是否合法
                if (StringUtil.isBlank(cellValue)) {
                    throw new IllegalArgumentException(tableName + " loadAll method must assign value for pk,row:" + i + " pk field:" + entityMeta.getIdArray()[j]);
                }
                realValues[index] = cellValue;
                index++;
            }
        }
        // 组织loadAll sql语句
        String sql = wrapLoadAll(entityMeta, idValues.size(), tableName, lockSqlHandler, lockMode, dbType);
        sqlToyResult = SqlConfigParseUtils.processSql(sql, null, realValues, null);
    }
    SqlExecuteStat.showSql("执行依据主键批量查询", sqlToyResult.getSql(), sqlToyResult.getParamsValue());
    List<?> entitySet = SqlUtil.findByJdbcQuery(sqlToyContext.getTypeHandler(), sqlToyResult.getSql(), sqlToyResult.getParamsValue(), entityClass, null, decryptHandler, conn, dbType, false, entityMeta.getColumnFieldMap(), fetchSize, maxRows);
    // 处理类中的@Translate注解,进行缓存翻译
    ResultUtils.wrapResultTranslate(sqlToyContext, entitySet, entityClass);
    if (entitySet == null || entitySet.isEmpty()) {
        return entitySet;
    }
    // 存在主表对应子表
    if (null != cascadeTypes && !cascadeTypes.isEmpty() && !entityMeta.getCascadeModels().isEmpty()) {
        StringBuilder subTableSql = new StringBuilder();
        List items;
        SqlToyResult subToyResult;
        EntityMeta mappedMeta;
        int fieldSize;
        List<Object[]> idValues = null;
        String colName;
        Object[] rowData;
        Object cellValue;
        for (TableCascadeModel cascadeModel : entityMeta.getCascadeModels()) {
            if (cascadeTypes.contains(cascadeModel.getMappedType())) {
                mappedMeta = sqlToyContext.getEntityMeta(cascadeModel.getMappedType());
                // 清空buffer
                subTableSql.delete(0, subTableSql.length());
                // 构造查询语句,update 2019-12-09 使用完整字段
                subTableSql.append(ReservedWordsUtil.convertSimpleSql(mappedMeta.getLoadAllSql(), dbType)).append(" where ");
                String orderCols = "";
                boolean hasOrder = StringUtil.isNotBlank(cascadeModel.getOrderBy());
                boolean hasExtCondtion = StringUtil.isNotBlank(cascadeModel.getLoadExtCondition()) ? true : false;
                fieldSize = cascadeModel.getMappedFields().length;
                // 单主键
                if (fieldSize == 1) {
                    colName = cascadeModel.getMappedColumns()[0];
                    colName = ReservedWordsUtil.convertWord(colName, dbType);
                    subTableSql.append(colName);
                    subTableSql.append(" in (?) ");
                    if (hasOrder) {
                        orderCols = orderCols.concat(colName).concat(",");
                    }
                } else // 复合主键
                {
                    // 构造(field1=? and field2=?)
                    String condition = " (";
                    for (int i = 0; i < fieldSize; i++) {
                        colName = cascadeModel.getMappedColumns()[i];
                        colName = ReservedWordsUtil.convertWord(colName, dbType);
                        if (i > 0) {
                            condition = condition.concat(" and ");
                        }
                        condition = condition.concat(colName).concat("=?");
                        if (hasOrder) {
                            orderCols = orderCols.concat(colName).concat(",");
                        }
                    }
                    condition = condition.concat(") ");
                    // 构造成 (field1=? and field2=?) or (field1=? and field2=?)
                    if (hasExtCondtion) {
                        subTableSql.append(" (");
                    }
                    idValues = BeanUtil.reflectBeansToInnerAry(entitySet, cascadeModel.getFields(), null, null);
                    for (int i = 0; i < idValues.size(); i++) {
                        if (i > 0) {
                            subTableSql.append(" or ");
                        }
                        subTableSql.append(condition);
                    }
                    if (hasExtCondtion) {
                        subTableSql.append(") ");
                    }
                }
                // 自定义扩展条件
                if (hasExtCondtion) {
                    subTableSql.append(" and ").append(cascadeModel.getLoadExtCondition());
                }
                if (hasOrder) {
                    subTableSql.append(" order by ").append(orderCols).append(cascadeModel.getOrderBy());
                }
                // 单主键
                if (fieldSize == 1) {
                    Object[] pkValues = BeanUtil.sliceToArray(entitySet, cascadeModel.getFields()[0]);
                    subToyResult = SqlConfigParseUtils.processSql(subTableSql.toString(), null, new Object[] { pkValues }, null);
                } else {
                    // 复合主键,将条件值构造成一个数组
                    Object[] realValues = new Object[idValues.size() * fieldSize];
                    int index = 0;
                    for (int i = 0, n = idValues.size(); i < n; i++) {
                        rowData = idValues.get(i);
                        for (int j = 0; j < fieldSize; j++) {
                            cellValue = rowData[j];
                            realValues[index] = cellValue;
                            index++;
                        }
                    }
                    subToyResult = SqlConfigParseUtils.processSql(subTableSql.toString(), null, realValues, null);
                }
                SqlExecuteStat.showSql("执行级联加载子表", subToyResult.getSql(), subToyResult.getParamsValue());
                // 加密字段解密
                DecryptHandler subDecryptHandler = null;
                if (mappedMeta.getSecureColumns() != null) {
                    subDecryptHandler = new DecryptHandler(sqlToyContext.getFieldsSecureProvider(), mappedMeta.getSecureColumns());
                }
                items = SqlUtil.findByJdbcQuery(sqlToyContext.getTypeHandler(), subToyResult.getSql(), subToyResult.getParamsValue(), cascadeModel.getMappedType(), null, subDecryptHandler, conn, dbType, false, mappedMeta.getColumnFieldMap(), SqlToyConstants.FETCH_SIZE, maxRows);
                // 处理子类中的@Translate注解,进行缓存翻译
                ResultUtils.wrapResultTranslate(sqlToyContext, items, cascadeModel.getMappedType());
                SqlExecuteStat.debug("子表加载结果", "子记录数:{} 条", items.size());
                // 将item的值分配映射到main主表对象上
                BeanUtil.loadAllMapping(entitySet, items, cascadeModel);
            }
        }
    }
    return entitySet;
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) DecryptHandler(org.sagacity.sqltoy.callback.DecryptHandler) TableCascadeModel(org.sagacity.sqltoy.config.model.TableCascadeModel) SqlToyResult(org.sagacity.sqltoy.config.model.SqlToyResult) List(java.util.List) ArrayList(java.util.ArrayList)

Example 2 with DecryptHandler

use of org.sagacity.sqltoy.callback.DecryptHandler in project sagacity-sqltoy by chenrenfei.

the class DialectFactory method wrapDecryptHandler.

/**
 * @TODO 构造加解密处理器
 * @param sqlToyContext
 * @param resultType
 * @return
 */
private DecryptHandler wrapDecryptHandler(final SqlToyContext sqlToyContext, Type resultType) {
    // 只针对POJO 实体类
    if (resultType == null || resultType.equals(Map.class) || resultType.equals(HashMap.class) || resultType.equals(List.class)) {
        return null;
    }
    FieldsSecureProvider fieldsSecureProvider = sqlToyContext.getFieldsSecureProvider();
    if (fieldsSecureProvider == null) {
        return null;
    }
    EntityMeta entityMeta = null;
    if (sqlToyContext.isEntity((Class) resultType)) {
        entityMeta = sqlToyContext.getEntityMeta((Class) resultType);
    }
    if (entityMeta == null || entityMeta.getSecureColumns() == null) {
        return null;
    }
    return new DecryptHandler(fieldsSecureProvider, entityMeta.getSecureColumns());
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) DecryptHandler(org.sagacity.sqltoy.callback.DecryptHandler) List(java.util.List) ArrayList(java.util.ArrayList) FieldsSecureProvider(org.sagacity.sqltoy.plugins.secure.FieldsSecureProvider) Map(java.util.Map) HashMap(java.util.HashMap)

Example 3 with DecryptHandler

use of org.sagacity.sqltoy.callback.DecryptHandler in project sagacity-sqltoy by chenrenfei.

the class DialectUtils method load.

/**
 * @todo 加载获取单笔数据库记录
 * @param sqlToyContext
 * @param sqlToyConfig
 * @param sql
 * @param entityMeta
 * @param entity
 * @param cascadeTypes
 * @param conn
 * @param dbType
 * @return
 * @throws Exception
 */
public static Serializable load(final SqlToyContext sqlToyContext, SqlToyConfig sqlToyConfig, String sql, EntityMeta entityMeta, Serializable entity, List<Class> cascadeTypes, Connection conn, final Integer dbType) throws Exception {
    Object[] pkValues = BeanUtil.reflectBeanToAry(entity, entityMeta.getIdArray());
    // 检查主键值是否合法
    for (int i = 0; i < pkValues.length; i++) {
        if (StringUtil.isBlank(pkValues[i])) {
            throw new IllegalArgumentException(entityMeta.getSchemaTable(null, dbType) + " load method must assign value for pk,null pk field is:" + entityMeta.getIdArray()[i]);
        }
    }
    SqlToyResult sqlToyResult = SqlConfigParseUtils.processSql(sql, entityMeta.getIdArray(), pkValues, null);
    // 加密字段解密
    DecryptHandler decryptHandler = null;
    if (entityMeta.getSecureColumns() != null) {
        decryptHandler = new DecryptHandler(sqlToyContext.getFieldsSecureProvider(), entityMeta.getSecureColumns());
    }
    QueryResult queryResult = findBySql(sqlToyContext, sqlToyConfig, sqlToyResult.getSql(), sqlToyResult.getParamsValue(), null, decryptHandler, conn, dbType, 0, -1, -1);
    List rows = queryResult.getRows();
    Serializable result = null;
    Class entityClass;
    if (rows != null && rows.size() > 0) {
        entityClass = BeanUtil.getEntityClass(entity.getClass());
        rows = BeanUtil.reflectListToBean(sqlToyContext.getTypeHandler(), rows, ResultUtils.humpFieldNames(queryResult.getLabelNames(), entityMeta.getColumnFieldMap()), entityClass);
        result = (Serializable) rows.get(0);
        // 处理类中的@Translate注解,进行缓存翻译
        ResultUtils.wrapResultTranslate(sqlToyContext, result, entityClass);
    }
    if (result == null) {
        return null;
    }
    // 存在主表对应子表
    if (null != cascadeTypes && !cascadeTypes.isEmpty() && !entityMeta.getCascadeModels().isEmpty()) {
        List pkRefDetails;
        EntityMeta mappedMeta;
        Object[] mainFieldValues;
        String loadSubTableSql;
        for (TableCascadeModel cascadeModel : entityMeta.getCascadeModels()) {
            // 判定是否要加载
            if (cascadeTypes.contains(cascadeModel.getMappedType())) {
                mainFieldValues = BeanUtil.reflectBeanToAry(result, cascadeModel.getFields());
                loadSubTableSql = ReservedWordsUtil.convertSql(cascadeModel.getLoadSubTableSql(), dbType);
                sqlToyResult = SqlConfigParseUtils.processSql(loadSubTableSql, cascadeModel.getMappedFields(), mainFieldValues, null);
                SqlExecuteStat.showSql("级联子表加载查询", sqlToyResult.getSql(), sqlToyResult.getParamsValue());
                mappedMeta = sqlToyContext.getEntityMeta(cascadeModel.getMappedType());
                // 子表加密字段解密
                DecryptHandler subDecryptHandler = null;
                if (mappedMeta.getSecureColumns() != null) {
                    subDecryptHandler = new DecryptHandler(sqlToyContext.getFieldsSecureProvider(), mappedMeta.getSecureColumns());
                }
                pkRefDetails = SqlUtil.findByJdbcQuery(sqlToyContext.getTypeHandler(), sqlToyResult.getSql(), sqlToyResult.getParamsValue(), cascadeModel.getMappedType(), null, subDecryptHandler, conn, dbType, false, mappedMeta.getColumnFieldMap(), SqlToyConstants.FETCH_SIZE, -1);
                // 处理子类中@Translate注解,进行缓存翻译
                ResultUtils.wrapResultTranslate(sqlToyContext, pkRefDetails, cascadeModel.getMappedType());
                if (null != pkRefDetails && !pkRefDetails.isEmpty()) {
                    // oneToMany
                    if (cascadeModel.getCascadeType() == 1) {
                        BeanUtil.setProperty(result, cascadeModel.getProperty(), pkRefDetails);
                    } else {
                        BeanUtil.setProperty(result, cascadeModel.getProperty(), pkRefDetails.get(0));
                    }
                }
            }
        }
    }
    return result;
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) Serializable(java.io.Serializable) DecryptHandler(org.sagacity.sqltoy.callback.DecryptHandler) TableCascadeModel(org.sagacity.sqltoy.config.model.TableCascadeModel) SqlToyResult(org.sagacity.sqltoy.config.model.SqlToyResult) QueryResult(org.sagacity.sqltoy.model.QueryResult) List(java.util.List) ArrayList(java.util.ArrayList)

Example 4 with DecryptHandler

use of org.sagacity.sqltoy.callback.DecryptHandler in project sagacity-sqltoy by chenrenfei.

the class ResultUtils method processResultSet.

/**
 * @todo 处理sql查询时的结果集,当没有反调或voClass反射处理时以数组方式返回resultSet的数据
 * @param sqlToyContext
 * @param sqlToyConfig
 * @param conn
 * @param rs
 * @param rowCallbackHandler
 * @param updateRowHandler
 * @param decryptHandler
 * @param startColIndex
 * @return
 * @throws Exception
 */
public static QueryResult processResultSet(final SqlToyContext sqlToyContext, final SqlToyConfig sqlToyConfig, Connection conn, ResultSet rs, RowCallbackHandler rowCallbackHandler, UpdateRowHandler updateRowHandler, DecryptHandler decryptHandler, int startColIndex) throws Exception {
    QueryResult result = new QueryResult();
    // 记录行记数器
    int index = 0;
    if (rowCallbackHandler != null) {
        while (rs.next()) {
            rowCallbackHandler.processRow(rs, index);
            index++;
        }
        result.setRows(rowCallbackHandler.getResult());
    } else {
        // 重新组合解密字段(entityMeta中的和sql自定义的合并)
        IgnoreCaseSet decryptColumns = (decryptHandler == null) ? null : decryptHandler.getColumns();
        if (sqlToyConfig.getDecryptColumns() != null) {
            if (decryptColumns == null) {
                decryptColumns = sqlToyConfig.getDecryptColumns();
            } else {
                decryptColumns.addAll(sqlToyConfig.getDecryptColumns());
            }
        }
        DecryptHandler realDecryptHandler = null;
        if (decryptColumns != null && !decryptColumns.isEmpty()) {
            realDecryptHandler = new DecryptHandler(sqlToyContext.getFieldsSecureProvider(), decryptColumns);
        }
        // 取得字段列数,在没有rowCallbackHandler時用数组返回
        int rowCnt = rs.getMetaData().getColumnCount();
        // 类型转成string的列
        Set<String> strTypeCols = getStringColumns(sqlToyConfig);
        boolean hasToStrCols = !strTypeCols.isEmpty();
        String[] labelNames = new String[rowCnt - startColIndex];
        String[] labelTypes = new String[rowCnt - startColIndex];
        HashMap<String, Integer> labelIndexMap = new HashMap<String, Integer>();
        String labeNameLow;
        for (int i = startColIndex; i < rowCnt; i++) {
            labelNames[index] = rs.getMetaData().getColumnLabel(i + 1);
            labeNameLow = labelNames[index].toLowerCase();
            labelIndexMap.put(labeNameLow, index);
            labelTypes[index] = rs.getMetaData().getColumnTypeName(i + 1);
            // 类型因缓存翻译、格式化转为string
            if (hasToStrCols) {
                if (strTypeCols.contains(labeNameLow)) {
                    labelTypes[index] = "VARCHAR";
                }
            }
            index++;
        }
        result.setLabelNames(labelNames);
        result.setLabelTypes(labelTypes);
        // 返回结果为非VO class时才可以应用旋转和汇总合计功能
        try {
            result.setRows(getResultSet(sqlToyConfig, sqlToyContext, conn, rs, updateRowHandler, realDecryptHandler, rowCnt, labelIndexMap, labelNames, startColIndex));
        }// update 2019-09-11 此处增加数组溢出异常是因为经常有开发设置缓存cache-indexs时写错误,为了增加错误提示信息的友好性增加此处理
         catch (Exception oie) {
            logger.error("sql={} 提取结果发生异常:{}!", sqlToyConfig.getId(), oie.getMessage());
            throw oie;
        }
    }
    // 填充记录数
    if (result.getRows() != null) {
        result.setRecordCount(Long.valueOf(result.getRows().size()));
    }
    return result;
}
Also used : QueryResult(org.sagacity.sqltoy.model.QueryResult) DecryptHandler(org.sagacity.sqltoy.callback.DecryptHandler) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) IgnoreCaseSet(org.sagacity.sqltoy.model.IgnoreCaseSet) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Aggregations

DecryptHandler (org.sagacity.sqltoy.callback.DecryptHandler)4 ArrayList (java.util.ArrayList)3 List (java.util.List)3 EntityMeta (org.sagacity.sqltoy.config.model.EntityMeta)3 HashMap (java.util.HashMap)2 SqlToyResult (org.sagacity.sqltoy.config.model.SqlToyResult)2 TableCascadeModel (org.sagacity.sqltoy.config.model.TableCascadeModel)2 QueryResult (org.sagacity.sqltoy.model.QueryResult)2 Serializable (java.io.Serializable)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 DataAccessException (org.sagacity.sqltoy.exception.DataAccessException)1 IgnoreCaseSet (org.sagacity.sqltoy.model.IgnoreCaseSet)1 FieldsSecureProvider (org.sagacity.sqltoy.plugins.secure.FieldsSecureProvider)1