Search in sources :

Example 21 with SqlToyResult

use of org.sagacity.sqltoy.config.model.SqlToyResult in project sagacity-sqltoy by chenrenfei.

the class MongoElasticUtils method wrapNoSql.

/**
 * @TODO 处理elastic sql
 * @param sqlToyConfig
 * @param paramNames
 * @param paramValues
 * @return
 */
private static SqlToyResult wrapNoSql(SqlToyConfig sqlToyConfig, String[] paramNames, Object[] paramValues) {
    String mql = sqlToyConfig.getSql(null);
    // 提取条件参数
    String[] fullNames = null;
    if (sqlToyConfig.getNoSqlConfigModel().isSqlMode()) {
        fullNames = SqlConfigParseUtils.getSqlParamsName(mql, false);
    } else {
        fullNames = SqlConfigParseUtils.getNoSqlParamsName(mql, false);
    }
    // 提取参数值
    Object[] fullParamValues = SqlConfigParseUtils.matchNamedParam(fullNames, paramNames, paramValues);
    SqlToyResult sqlToyResult = processNullConditions(mql, fullParamValues, sqlToyConfig.getNoSqlConfigModel().isSqlMode());
    // 处理@blank(:name)
    processBlank(sqlToyResult);
    // 处理@value(:name)
    processValue(sqlToyResult);
    return sqlToyResult;
}
Also used : SqlToyResult(org.sagacity.sqltoy.config.model.SqlToyResult)

Example 22 with SqlToyResult

use of org.sagacity.sqltoy.config.model.SqlToyResult in project sagacity-sqltoy by chenrenfei.

the class MongoElasticUtils method processNullConditions.

/**
 * @todo 处理sql中的参数过滤逻辑
 * @param queryStr
 * @param paramValues
 * @param sqlMode
 * @return
 */
private static SqlToyResult processNullConditions(String queryStr, Object[] paramValues, boolean sqlMode) {
    SqlToyResult sqlToyResult = new SqlToyResult();
    sqlToyResult.setSql(queryStr);
    sqlToyResult.setParamsValue(paramValues);
    if (queryStr.indexOf(SQL_PSEUDO_START_MARK) == -1 && queryStr.indexOf(MQL_PSEUDO_START_MARK) == -1) {
        return sqlToyResult;
    }
    boolean isMqlMark = false;
    if (queryStr.indexOf(MQL_PSEUDO_START_MARK) != -1) {
        isMqlMark = true;
    }
    // 兼容#[] 和<#></#> 两种模式配置
    String startMark = isMqlMark ? MQL_PSEUDO_START_MARK : SQL_PSEUDO_START_MARK;
    String endMark = isMqlMark ? MQL_PSEUDO_END_MARK : SQL_PSEUDO_END_MARK;
    Pattern namedPattern = sqlMode ? SqlToyConstants.SQL_NAMED_PATTERN : SqlToyConstants.NOSQL_NAMED_PATTERN;
    int startMarkLength = startMark.length();
    int endMarkLength = endMark.length();
    int pseudoMarkStart = queryStr.indexOf(startMark);
    int beginIndex, endIndex, paramCnt, preParamCnt, beginMarkIndex, endMarkIndex;
    String preSql, markContentSql, tailSql;
    List paramValuesList = CollectionUtil.arrayToList(paramValues);
    boolean logicValue = true;
    int start;
    int end;
    String evalStr;
    int logicParamCnt;
    Object paramValue;
    boolean isNull;
    while (pseudoMarkStart != -1) {
        // 始终从最后一个#[]进行处理
        beginMarkIndex = queryStr.lastIndexOf(startMark);
        // update 2021-01-17 兼容sql中存在"["和"]"符号场景
        if (startMark.equals(SQL_PSEUDO_START_MARK)) {
            endMarkIndex = StringUtil.getSymMarkIndex(SQL_PSEUDO_SYM_START_MARK, endMark, queryStr, beginMarkIndex);
        } else {
            endMarkIndex = StringUtil.getSymMarkIndex(startMark, endMark, queryStr, beginMarkIndex + startMarkLength);
        }
        // 最后一个#[前的sql
        preSql = queryStr.substring(0, beginMarkIndex).concat(BLANK);
        // 最后#[]中的查询语句,加空白减少substr(index+1)可能引起的错误
        markContentSql = BLANK.concat(queryStr.substring(beginMarkIndex + startMarkLength, endMarkIndex)).concat(BLANK);
        tailSql = queryStr.substring(endMarkIndex + endMarkLength);
        // 获取#[]中的参数数量
        paramCnt = StringUtil.matchCnt(markContentSql, namedPattern);
        // #[]中无参数,拼接preSql+markContentSql+tailSql
        if (paramCnt == 0) {
            queryStr = preSql.concat(BLANK).concat(tailSql);
        } else {
            // 在#[前的参数个数
            preParamCnt = StringUtil.matchCnt(preSql, namedPattern);
            logicValue = true;
            start = markContentSql.toLowerCase().indexOf("@if(");
            // sql中存在逻辑判断
            if (start > -1) {
                end = StringUtil.getSymMarkIndex("(", ")", markContentSql, start);
                evalStr = BLANK.concat(markContentSql.substring(markContentSql.indexOf("(", start) + 1, end));
                logicParamCnt = StringUtil.matchCnt(evalStr, namedPattern);
                // update 2017-4-14 增加@if()简单逻辑判断
                logicValue = MacroIfLogic.evalLogic(evalStr, paramValuesList, preParamCnt, logicParamCnt);
                // 逻辑不成立,剔除sql和对应参数
                if (!logicValue) {
                    markContentSql = BLANK;
                    for (int k = paramCnt; k > 0; k--) {
                        paramValuesList.remove(k + preParamCnt - 1);
                    }
                } else {
                    // 逻辑成立,去除@if()部分sql和对应的参数,同时将剩余参数数量减掉@if()中的参数数量
                    markContentSql = markContentSql.substring(0, start).concat(markContentSql.substring(end + 1));
                    for (int k = 0; k < logicParamCnt; k++) {
                        paramValuesList.remove(preParamCnt);
                    }
                    paramCnt = paramCnt - logicParamCnt;
                }
            }
            // 逻辑成立,继续sql中参数是否为null的逻辑判断
            if (logicValue) {
                beginIndex = 0;
                endIndex = 0;
                // 按顺序处理#[]中sql的参数
                for (int i = preParamCnt; i < preParamCnt + paramCnt; i++) {
                    paramValue = paramValuesList.get(i);
                    beginIndex = endIndex;
                    endIndex = StringUtil.matchIndex(markContentSql.substring(beginIndex), namedPattern);
                    isNull = false;
                    if (null == paramValue) {
                        isNull = true;
                    } else if (null != paramValue) {
                        if (paramValue.getClass().isArray() && CollectionUtil.convertArray(paramValue).length == 0) {
                            isNull = true;
                        } else if ((paramValue instanceof Collection) && ((Collection) paramValue).isEmpty()) {
                            isNull = true;
                        }
                    }
                    // 2、is 条件sql语句值非null、true、false 剔除#[]部分内容,同时将参数从数组中剔除
                    if (isNull) {
                        // sql中剔除最后部分的#[]内容
                        markContentSql = BLANK;
                        for (int k = paramCnt; k > 0; k--) {
                            paramValuesList.remove(k + preParamCnt - 1);
                        }
                        break;
                    }
                }
            }
            if (sqlMode) {
                queryStr = SqlConfigParseUtils.processWhereLinkAnd(preSql, markContentSql, tailSql);
            } else {
                queryStr = preSql.concat(BLANK).concat(markContentSql).concat(BLANK).concat(tailSql);
            }
        }
        pseudoMarkStart = queryStr.indexOf(startMark);
    }
    sqlToyResult.setSql(sqlMode ? queryStr : processComma(queryStr));
    sqlToyResult.setParamsValue(paramValuesList.toArray());
    return sqlToyResult;
}
Also used : Pattern(java.util.regex.Pattern) Collection(java.util.Collection) List(java.util.List) SqlToyResult(org.sagacity.sqltoy.config.model.SqlToyResult)

Example 23 with SqlToyResult

use of org.sagacity.sqltoy.config.model.SqlToyResult in project sagacity-sqltoy by chenrenfei.

the class DialectUtils method update.

/**
 * @todo 单个对象修改,包含接连修改
 * @param sqlToyContext
 * @param entity
 * @param nullFunction
 * @param forceUpdateFields
 * @param cascade
 * @param generateSqlHandler
 * @param forceCascadeClasses
 * @param subTableForceUpdateProps
 * @param conn
 * @param tableName
 * @throws Exception
 */
public static Long update(SqlToyContext sqlToyContext, Serializable entity, String nullFunction, String[] forceUpdateFields, final boolean cascade, final GenerateSqlHandler generateSqlHandler, final Class[] forceCascadeClasses, final HashMap<Class, String[]> subTableForceUpdateProps, Connection conn, final Integer dbType, String tableName) throws Exception {
    EntityMeta entityMeta = sqlToyContext.getEntityMeta(entity.getClass());
    String realTable = entityMeta.getSchemaTable(tableName, dbType);
    // 无主键
    if (entityMeta.getIdArray() == null) {
        throw new IllegalArgumentException("表:" + realTable + " 无主键,不符合update/updateAll规则,请检查表设计是否合理!");
    }
    // 全部是主键则无需update
    if (entityMeta.getRejectIdFieldArray() == null) {
        logger.warn("表:" + realTable + " 字段全部是主键不存在更新字段,无需执行更新操作!");
        return 0L;
    }
    Long updateCnt = update(sqlToyContext, entity, entityMeta, nullFunction, forceUpdateFields, conn, dbType, tableName);
    // 不存在级联操作
    if (!cascade || entityMeta.getCascadeModels().isEmpty()) {
        return updateCnt;
    }
    // 级联保存
    HashMap<Type, String> typeMap = new HashMap<Type, String>();
    // 即使子对象数据是null,也强制进行级联修改(null表示删除子表数据)
    if (forceCascadeClasses != null) {
        for (Type type : forceCascadeClasses) {
            typeMap.put(type, "");
        }
    }
    // 级联子表数据
    List subTableData = null;
    String[] forceUpdateProps = null;
    EntityMeta subTableEntityMeta;
    // 对子表进行级联处理
    for (TableCascadeModel cascadeModel : entityMeta.getCascadeModels()) {
        final Object[] mainFieldValues = BeanUtil.reflectBeanToAry(entity, cascadeModel.getFields());
        subTableEntityMeta = sqlToyContext.getEntityMeta(cascadeModel.getMappedType());
        forceUpdateProps = (subTableForceUpdateProps == null) ? null : subTableForceUpdateProps.get(cascadeModel.getMappedType());
        // oneToMany
        if (cascadeModel.getCascadeType() == 1) {
            subTableData = (List) BeanUtil.getProperty(entity, cascadeModel.getProperty());
        } else {
            subTableData = new ArrayList();
            Object item = BeanUtil.getProperty(entity, cascadeModel.getProperty());
            if (item != null) {
                subTableData.add(item);
            }
        }
        final String[] mappedFields = cascadeModel.getMappedFields();
        // 针对子表存量数据,调用级联修改的语句,分delete 和update两种操作 1、删除存量数据;2、设置存量数据状态为停用
        if (cascadeModel.getCascadeUpdateSql() != null && ((subTableData != null && !subTableData.isEmpty()) || typeMap.containsKey(cascadeModel.getMappedType()))) {
            SqlExecuteStat.debug("执行子表级联更新前的存量数据更新", null);
            // 根据quickvo配置文件针对cascade中update-cascade配置组织具体操作sql
            SqlToyResult sqlToyResult = SqlConfigParseUtils.processSql(cascadeModel.getCascadeUpdateSql(), mappedFields, mainFieldValues, null);
            SqlUtil.executeSql(sqlToyContext.getTypeHandler(), sqlToyResult.getSql(), sqlToyResult.getParamsValue(), null, conn, dbType, null, true);
        }
        // 子表数据不为空,采取saveOrUpdateAll操作
        if (subTableData != null && !subTableData.isEmpty()) {
            logger.info("执行update主表:{} 对应级联子表: {} 更新操作!", realTable, subTableEntityMeta.getTableName());
            SqlExecuteStat.debug("执行子表级联更新操作", null);
            // 将外键值通过反调赋到相关属性上
            ReflectPropsHandler reflectPropsHandler = new ReflectPropsHandler() {

                public void process() {
                    for (int i = 0; i < mappedFields.length; i++) {
                        this.setValue(mappedFields[i], mainFieldValues[i]);
                    }
                }
            };
            // 这里需要进行修改,mysql\postgresql\sqlite 等存在缺陷(字段值不为null时会报错)
            if (dbType == DBType.MYSQL || dbType == DBType.MYSQL57 || dbType == DBType.TIDB) {
                mysqlSaveOrUpdateAll(sqlToyContext, subTableEntityMeta, subTableData, reflectPropsHandler, forceUpdateProps, conn, dbType);
            } else if (dbType == DBType.POSTGRESQL || dbType == DBType.GAUSSDB) {
                postgreSaveOrUpdateAll(sqlToyContext, subTableEntityMeta, subTableData, reflectPropsHandler, forceUpdateProps, conn, dbType);
            } else if (dbType == DBType.OCEANBASE) {
                oceanBaseSaveOrUpdateAll(sqlToyContext, subTableEntityMeta, subTableData, reflectPropsHandler, forceUpdateProps, conn, dbType);
            } else if (dbType == DBType.SQLITE) {
                sqliteSaveOrUpdateAll(sqlToyContext, subTableEntityMeta, subTableData, reflectPropsHandler, forceUpdateProps, conn, dbType);
            } else // 达梦数据库
            if (dbType == DBType.DM) {
                dmSaveOrUpdateAll(sqlToyContext, subTableEntityMeta, subTableData, reflectPropsHandler, forceUpdateProps, conn, dbType);
            } else // kingbase
            if (dbType == DBType.KINGBASE) {
                kingbaseSaveOrUpdateAll(sqlToyContext, subTableEntityMeta, subTableData, reflectPropsHandler, forceUpdateProps, conn, dbType);
            } else // db2/oracle/mssql 通过merge 方式
            {
                saveOrUpdateAll(sqlToyContext, subTableData, sqlToyContext.getBatchSize(), subTableEntityMeta, forceUpdateProps, generateSqlHandler, // 设置关联外键字段的属性值(来自主表的主键)
                reflectPropsHandler, conn, dbType, null);
            }
        } else {
            logger.info("未执行update主表:{} 对应级联子表: {} 更新操作,子表数据为空!", realTable, subTableEntityMeta.getTableName());
        }
    }
    return updateCnt;
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) TableCascadeModel(org.sagacity.sqltoy.config.model.TableCascadeModel) ReflectPropsHandler(org.sagacity.sqltoy.callback.ReflectPropsHandler) SqlToyResult(org.sagacity.sqltoy.config.model.SqlToyResult) ReturnPkType(org.sagacity.sqltoy.dialect.model.ReturnPkType) Type(java.lang.reflect.Type) SecureType(org.sagacity.sqltoy.model.SecureType) DBType(org.sagacity.sqltoy.utils.DataSourceUtils.DBType) List(java.util.List) ArrayList(java.util.ArrayList)

Example 24 with SqlToyResult

use of org.sagacity.sqltoy.config.model.SqlToyResult 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 25 with SqlToyResult

use of org.sagacity.sqltoy.config.model.SqlToyResult in project sagacity-sqltoy by chenrenfei.

the class SqlServerDialectUtils method update.

/**
 * @todo 单个对象修改,包含级联修改
 * @param sqlToyContext
 * @param entity
 * @param forceUpdateFields
 * @param cascade
 * @param emptyCascadeClasses
 * @param subTableForceUpdateProps
 * @param conn
 * @param dbType
 * @param tableName
 * @return
 * @throws Exception
 */
public static Long update(SqlToyContext sqlToyContext, Serializable entity, String[] forceUpdateFields, final boolean cascade, final Class[] emptyCascadeClasses, final HashMap<Class, String[]> subTableForceUpdateProps, Connection conn, final Integer dbType, final String tableName) throws Exception {
    EntityMeta entityMeta = sqlToyContext.getEntityMeta(entity.getClass());
    String realTable = entityMeta.getSchemaTable(tableName, dbType);
    Long updateCount = DialectUtils.update(sqlToyContext, entity, entityMeta, "isnull", forceUpdateFields, conn, dbType, realTable);
    // 级联修改
    if (cascade && !entityMeta.getCascadeModels().isEmpty()) {
        HashMap<Type, String> typeMap = new HashMap<Type, String>();
        if (emptyCascadeClasses != null) {
            for (Type type : emptyCascadeClasses) {
                typeMap.put(type, "");
            }
        }
        // 级联子表数据
        List subTableData = null;
        String[] forceUpdateProps = null;
        EntityMeta subTableEntityMeta;
        for (TableCascadeModel cascadeModel : entityMeta.getCascadeModels()) {
            final Object[] mainFieldValues = BeanUtil.reflectBeanToAry(entity, cascadeModel.getFields());
            subTableEntityMeta = sqlToyContext.getEntityMeta(cascadeModel.getMappedType());
            forceUpdateProps = (subTableForceUpdateProps == null) ? null : subTableForceUpdateProps.get(cascadeModel.getMappedType());
            if (cascadeModel.getCascadeType() == 1) {
                subTableData = (List) BeanUtil.getProperty(entity, cascadeModel.getProperty());
            } else {
                subTableData = new ArrayList();
                Object item = BeanUtil.getProperty(entity, cascadeModel.getProperty());
                if (item != null) {
                    subTableData.add(item);
                }
            }
            final String[] mappedFields = cascadeModel.getMappedFields();
            // 针对存量子表数据,调用级联修改的语句,分delete 和update两种操作 1、删除存量数据;2、设置存量数据状态为停用
            if (cascadeModel.getCascadeUpdateSql() != null && ((subTableData != null && !subTableData.isEmpty()) || typeMap.containsKey(cascadeModel.getMappedType()))) {
                SqlExecuteStat.debug("执行子表级联更新前的存量数据更新", null);
                SqlToyResult sqlToyResult = SqlConfigParseUtils.processSql(cascadeModel.getCascadeUpdateSql(), mappedFields, mainFieldValues, null);
                SqlUtil.executeSql(sqlToyContext.getTypeHandler(), sqlToyResult.getSql(), sqlToyResult.getParamsValue(), null, conn, dbType, null, true);
            }
            // 子表数据不为空,采取saveOrUpdateAll操作
            if (subTableData != null && !subTableData.isEmpty()) {
                logger.info("执行update主表:{} 对应级联子表: {} 更新操作!", tableName, subTableEntityMeta.getTableName());
                SqlExecuteStat.debug("执行子表级联更新操作", null);
                saveOrUpdateAll(sqlToyContext, subTableData, sqlToyContext.getBatchSize(), // 设置关联外键字段的属性值(来自主表的主键)
                new ReflectPropsHandler() {

                    public void process() {
                        for (int i = 0; i < mappedFields.length; i++) {
                            this.setValue(mappedFields[i], mainFieldValues[i]);
                        }
                    }
                }, forceUpdateProps, conn, dbType, null, null);
            } else {
                logger.info("未执行update主表:{} 对应级联子表: {} 更新操作,子表数据为空!", tableName, subTableEntityMeta.getTableName());
            }
        }
    }
    return updateCount;
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) TableCascadeModel(org.sagacity.sqltoy.config.model.TableCascadeModel) ReflectPropsHandler(org.sagacity.sqltoy.callback.ReflectPropsHandler) SqlToyResult(org.sagacity.sqltoy.config.model.SqlToyResult) DBType(org.sagacity.sqltoy.utils.DataSourceUtils.DBType) Type(java.lang.reflect.Type) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

SqlToyResult (org.sagacity.sqltoy.config.model.SqlToyResult)74 QueryExecutorExtend (org.sagacity.sqltoy.model.inner.QueryExecutorExtend)19 List (java.util.List)16 ArrayList (java.util.ArrayList)15 SqlToyConfig (org.sagacity.sqltoy.config.model.SqlToyConfig)12 Connection (java.sql.Connection)11 DataSourceCallbackHandler (org.sagacity.sqltoy.callback.DataSourceCallbackHandler)11 QueryResult (org.sagacity.sqltoy.model.QueryResult)11 Test (org.junit.jupiter.api.Test)9 EntityMeta (org.sagacity.sqltoy.config.model.EntityMeta)8 BaseException (org.sagacity.sqltoy.exception.BaseException)6 SqlWithAnalysis (org.sagacity.sqltoy.config.model.SqlWithAnalysis)5 DataAccessException (org.sagacity.sqltoy.exception.DataAccessException)5 Type (java.lang.reflect.Type)4 HashMap (java.util.HashMap)4 OneToManyModel (org.sagacity.sqltoy.config.model.OneToManyModel)4 TableCascadeModel (org.sagacity.sqltoy.config.model.TableCascadeModel)4 DBType (org.sagacity.sqltoy.utils.DataSourceUtils.DBType)3 IOException (java.io.IOException)2 Serializable (java.io.Serializable)2