Search in sources :

Example 36 with DataSourceCallbackHandler

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

the class DialectFactory method deleteAll.

/**
 * @todo 批量删除对象
 * @param <T>
 * @param sqlToyContext
 * @param entities
 * @param batchSize
 * @param dataSource
 * @param autoCommit
 * @return
 */
public <T extends Serializable> Long deleteAll(final SqlToyContext sqlToyContext, final List<T> entities, final int batchSize, final DataSource dataSource, final Boolean autoCommit) {
    if (entities == null || entities.isEmpty()) {
        logger.warn("deleteAll entities is null or empty,please check!");
        return 0L;
    }
    try {
        SqlExecuteStat.start(BeanUtil.getEntityClass(entities.get(0).getClass()).getName(), "deleteAll:[" + entities.size() + "]条记录!", null);
        // 分库分表并行执行
        List<Long> result = ParallelUtils.execute(sqlToyContext, entities, false, dataSource, (context, batchModel) -> {
            final ShardingModel shardingModel = batchModel.getShardingModel();
            Long updateCnt = (Long) DataSourceUtils.processDataSource(context, shardingModel.getDataSource(), new DataSourceCallbackHandler() {

                @Override
                public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
                    this.setResult(getDialectSqlWrapper(dbType).deleteAll(context, batchModel.getEntities(), batchSize, conn, dbType, dialect, autoCommit, shardingModel.getTableName()));
                }
            });
            List<Long> tmp = new ArrayList();
            tmp.add(updateCnt);
            return tmp;
        });
        long updateTotalCnt = 0;
        if (result != null) {
            for (Long cnt : result) {
                updateTotalCnt = updateTotalCnt + cnt.longValue();
            }
        }
        SqlExecuteStat.debug("执行结果", "批量删除操作影响记录量:{} 条!", updateTotalCnt);
        return Long.valueOf(updateTotalCnt);
    } catch (Exception e) {
        SqlExecuteStat.error(e);
        throw new DataAccessException(e);
    } finally {
        SqlExecuteStat.destroy();
    }
}
Also used : Connection(java.sql.Connection) ArrayList(java.util.ArrayList) DataSourceCallbackHandler(org.sagacity.sqltoy.callback.DataSourceCallbackHandler) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) ShardingModel(org.sagacity.sqltoy.config.model.ShardingModel)

Example 37 with DataSourceCallbackHandler

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

the class DialectFactory method getCountBySql.

/**
 * @todo 查询符合条件的记录数量
 * @param sqlToyContext
 * @param queryExecutor
 * @param sqlToyConfig
 * @param dataSource
 * @return
 */
public Long getCountBySql(final SqlToyContext sqlToyContext, final QueryExecutor queryExecutor, final SqlToyConfig sqlToyConfig, final DataSource dataSource) {
    final QueryExecutorExtend extend = queryExecutor.getInnerModel();
    if (StringUtil.isBlank(extend.sql)) {
        throw new IllegalArgumentException("getCountBySql operate sql is null!");
    }
    try {
        // 规整查询参数名称和参数名称对应的值
        QueryExecutorBuilder.initQueryExecutor(sqlToyContext, extend, sqlToyConfig, false);
        SqlExecuteStat.start(sqlToyConfig.getId(), "getCountBySql", sqlToyConfig.isShowSql());
        Long count = (Long) DataSourceUtils.processDataSource(sqlToyContext, ShardingUtils.getShardingDataSource(sqlToyContext, sqlToyConfig, queryExecutor, dataSource), new DataSourceCallbackHandler() {

            @Override
            public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
                // 处理sql中的?为统一的:named形式,并进行sharding table替换
                SqlToyConfig realSqlToyConfig = DialectUtils.getUnifyParamsNamedConfig(sqlToyContext, sqlToyConfig, queryExecutor, dialect, false);
                this.setResult(getCountBySql(sqlToyContext, realSqlToyConfig, queryExecutor, conn, dbType, dialect));
            }
        });
        SqlExecuteStat.debug("查询结果", "count查询结果={}!", count);
        return count;
    } catch (Exception e) {
        SqlExecuteStat.error(e);
        throw new DataAccessException(e);
    } finally {
        SqlExecuteStat.destroy();
    }
}
Also used : SqlToyConfig(org.sagacity.sqltoy.config.model.SqlToyConfig) Connection(java.sql.Connection) QueryExecutorExtend(org.sagacity.sqltoy.model.inner.QueryExecutorExtend) DataSourceCallbackHandler(org.sagacity.sqltoy.callback.DataSourceCallbackHandler) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 38 with DataSourceCallbackHandler

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

the class DialectFactory method findSkipTotalCountPage.

/**
 * @TODO 跳过查询总记录的分页查询,提供给特殊的场景,尤其是移动端滚屏模式
 * @param sqlToyContext
 * @param queryExecutor
 * @param sqlToyConfig
 * @param pageNo
 * @param pageSize
 * @param dataSource
 * @return
 */
public QueryResult findSkipTotalCountPage(final SqlToyContext sqlToyContext, final QueryExecutor queryExecutor, final SqlToyConfig sqlToyConfig, final long pageNo, final Integer pageSize, final DataSource dataSource) {
    final QueryExecutorExtend extend = queryExecutor.getInnerModel();
    if (StringUtil.isBlank(extend.sql)) {
        throw new IllegalArgumentException("findSkipTotalCountPage operate sql is null!");
    }
    // 页数必须要大于等于1,pageSize必须要大于1
    if (pageNo < 1 || pageSize < 1) {
        throw new IllegalArgumentException("findSkipTotalCountPage operate  pageSize:" + pageSize + "<1 or pageNo:" + pageNo + " < 1!");
    }
    int limitSize = sqlToyContext.getPageFetchSizeLimit();
    // 分页查询不允许单页数据超过上限,避免大规模数据提取
    if (pageSize >= limitSize) {
        throw new IllegalArgumentException("findSkipTotalCountPage operate args is Illegal,pageSize={" + pageSize + "}>= limit:{" + limitSize + "}!");
    }
    try {
        Long startTime = System.currentTimeMillis();
        // 规整查询参数名称和参数名称对应的值
        QueryExecutorBuilder.initQueryExecutor(sqlToyContext, extend, sqlToyConfig, false);
        SqlExecuteStat.start(sqlToyConfig.getId(), "findSkipTotalCountPage", sqlToyConfig.isShowSql());
        QueryResult result = (QueryResult) DataSourceUtils.processDataSource(sqlToyContext, ShardingUtils.getShardingDataSource(sqlToyContext, sqlToyConfig, queryExecutor, dataSource), new DataSourceCallbackHandler() {

            @Override
            public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
                // 处理sql中的?为统一的:named形式,并进行sharding table替换
                SqlToyConfig realSqlToyConfig = DialectUtils.getUnifyParamsNamedConfig(sqlToyContext, sqlToyConfig, queryExecutor, dialect, false);
                QueryResult queryResult = getDialectSqlWrapper(dbType).findPageBySql(sqlToyContext, realSqlToyConfig, queryExecutor, wrapDecryptHandler(sqlToyContext, extend.resultType), pageNo, pageSize, conn, dbType, dialect, getFetchSize(extend.fetchSize), extend.maxRows);
                queryResult.setPageNo(pageNo);
                queryResult.setPageSize(pageSize);
                if (queryResult.getRows() != null && !queryResult.getRows().isEmpty()) {
                    // 存在计算和旋转的数据不能映射到对象(数据类型不一致,如汇总平均以及数据旋转)
                    List pivotCategorySet = ResultUtils.getPivotCategory(sqlToyContext, realSqlToyConfig, queryExecutor, conn, dbType, dialect);
                    // 对查询结果进行计算处理:字段脱敏、格式化、数据旋转、同步环比、分组汇总等
                    boolean changedCols = ResultUtils.calculate(sqlToyContext.getDesensitizeProvider(), realSqlToyConfig, queryResult, pivotCategorySet, extend);
                    // 将结果映射对象单独出来为了解耦,性能影响其实可以忽略,上万条也是1毫秒级
                    if (extend.resultType != null) {
                        queryResult.setRows(ResultUtils.wrapQueryResult(sqlToyContext, queryResult.getRows(), queryResult.getLabelNames(), (Class) extend.resultType, changedCols, extend.humpMapLabel, extend.hiberarchy, extend.hiberarchyClasses, extend.fieldsMap));
                    }
                }
                queryResult.setSkipQueryCount(true);
                SqlExecuteStat.debug("查询结果", "分页查询出记录数量:{}条!", queryResult.getRecordCount());
                this.setResult(queryResult);
            }
        });
        result.setExecuteTime(System.currentTimeMillis() - startTime);
        return result;
    } catch (Exception e) {
        SqlExecuteStat.error(e);
        throw new DataAccessException(e);
    } finally {
        SqlExecuteStat.destroy();
    }
}
Also used : SqlToyConfig(org.sagacity.sqltoy.config.model.SqlToyConfig) Connection(java.sql.Connection) DataSourceCallbackHandler(org.sagacity.sqltoy.callback.DataSourceCallbackHandler) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) QueryResult(org.sagacity.sqltoy.model.QueryResult) List(java.util.List) ArrayList(java.util.ArrayList) QueryExecutorExtend(org.sagacity.sqltoy.model.inner.QueryExecutorExtend) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 39 with DataSourceCallbackHandler

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

the class DialectFactory method executeStore.

/**
 * @todo 存储过程调用
 * @param sqlToyContext
 * @param sqlToyConfig
 * @param inParamsValue
 * @param outParamsType
 * @param resultType
 * @param dataSource
 * @return
 */
public StoreResult executeStore(final SqlToyContext sqlToyContext, final SqlToyConfig sqlToyConfig, final Object[] inParamsValue, final Integer[] outParamsType, final Class resultType, final DataSource dataSource) {
    try {
        Long startTime = System.currentTimeMillis();
        SqlExecuteStat.start(sqlToyConfig.getId(), "executeStore", sqlToyConfig.isShowSql());
        StoreResult result = (StoreResult) DataSourceUtils.processDataSource(sqlToyContext, dataSource, new DataSourceCallbackHandler() {

            @Override
            public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
                String dialectSql = sqlToyConfig.getSql(dialect);
                int inCount = (inParamsValue == null) ? 0 : inParamsValue.length;
                int outCount = (outParamsType == null) ? 0 : outParamsType.length;
                // sql中问号数量
                int paramCnt = StringUtil.matchCnt(dialectSql, ARG_PATTERN);
                // 处理参数注入
                if (paramCnt != inCount + outCount) {
                    throw new IllegalArgumentException("存储过程语句中的输入和输出参数跟实际调用传递的数量不等!");
                }
                SqlToyResult sqlToyResult = new SqlToyResult(dialectSql, inParamsValue);
                // 判断是否是{?=call xxStore()} 模式(oracle 不支持此模式)
                boolean isFirstResult = StringUtil.matches(dialectSql, STORE_PATTERN);
                // 将call xxxStore(?,?) 后的条件参数判断是否为null,如果是null则改为call xxxStore(null,?,null)
                // 避免设置类型错误
                SqlConfigParseUtils.replaceNull(sqlToyResult, isFirstResult ? 1 : 0);
                // 针对不同数据库执行存储过程调用
                SqlExecuteStat.showSql("存储过程执行", sqlToyResult.getSql(), sqlToyResult.getParamsValue());
                StoreResult queryResult = getDialectSqlWrapper(dbType).executeStore(sqlToyContext, sqlToyConfig, sqlToyResult.getSql(), sqlToyResult.getParamsValue(), outParamsType, conn, dbType, dialect, -1);
                // 进行数据必要的数据处理(一般存储过程不会结合旋转sql进行数据旋转操作)
                // {此区域代码正常情况下不会使用
                QueryExecutor queryExecutor = new QueryExecutor(null, sqlToyConfig.getParamsName(), inParamsValue);
                List pivotCategorySet = ResultUtils.getPivotCategory(sqlToyContext, sqlToyConfig, queryExecutor, conn, dbType, dialect);
                boolean changedCols = ResultUtils.calculate(sqlToyContext.getDesensitizeProvider(), sqlToyConfig, queryResult, pivotCategorySet, null);
                // 映射成对象
                if (resultType != null) {
                    queryResult.setRows(ResultUtils.wrapQueryResult(sqlToyContext, queryResult.getRows(), queryResult.getLabelNames(), resultType, changedCols, true, false, null, null));
                }
                SqlExecuteStat.debug("执行结果", "存储过程影响记录:{} 条!", queryResult.getRecordCount());
                this.setResult(queryResult);
            }
        });
        result.setExecuteTime(System.currentTimeMillis() - startTime);
        return result;
    } catch (Exception e) {
        SqlExecuteStat.error(e);
        throw new DataAccessException(e);
    } finally {
        SqlExecuteStat.destroy();
    }
}
Also used : Connection(java.sql.Connection) DataSourceCallbackHandler(org.sagacity.sqltoy.callback.DataSourceCallbackHandler) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) SqlToyResult(org.sagacity.sqltoy.config.model.SqlToyResult) QueryExecutor(org.sagacity.sqltoy.model.QueryExecutor) StoreResult(org.sagacity.sqltoy.model.StoreResult) List(java.util.List) ArrayList(java.util.ArrayList) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 40 with DataSourceCallbackHandler

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

the class DialectFactory method saveOrUpdateAll.

/**
 * @todo 批量保存或修改数据
 * @param sqlToyContext
 * @param entities
 * @param batchSize
 * @param forceUpdateProps
 * @param reflectPropsHandler
 * @param dataSource
 * @param autoCommit
 */
public Long saveOrUpdateAll(final SqlToyContext sqlToyContext, final List<?> entities, final int batchSize, final String[] forceUpdateProps, final ReflectPropsHandler reflectPropsHandler, final DataSource dataSource, final Boolean autoCommit) {
    // 前置输入合法校验
    if (entities == null || entities.isEmpty()) {
        logger.warn("saveOrUpdateAll entities is null or empty,please check!");
        return 0L;
    }
    try {
        // 启动执行日志
        SqlExecuteStat.start(BeanUtil.getEntityClass(entities.get(0).getClass()).getName(), "saveOrUpdateAll:[" + entities.size() + "]条记录!", null);
        List<Long> result = ParallelUtils.execute(sqlToyContext, entities, true, dataSource, (context, batchModel) -> {
            ShardingModel shardingModel = batchModel.getShardingModel();
            Long updateCnt = (Long) DataSourceUtils.processDataSource(context, shardingModel.getDataSource(), new DataSourceCallbackHandler() {

                @Override
                public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
                    this.setResult(getDialectSqlWrapper(dbType).saveOrUpdateAll(context, batchModel.getEntities(), batchSize, reflectPropsHandler, forceUpdateProps, conn, dbType, dialect, autoCommit, shardingModel.getTableName()));
                }
            });
            List<Long> tmp = new ArrayList();
            tmp.add(updateCnt);
            return tmp;
        });
        long updateTotalCnt = 0;
        if (result != null) {
            for (Long cnt : result) {
                updateTotalCnt = updateTotalCnt + cnt.longValue();
            }
        }
        // 输出修改记录量日志
        SqlExecuteStat.debug("执行结果", "实际影响记录数量:{} 条!", updateTotalCnt);
        return Long.valueOf(updateTotalCnt);
    } catch (Exception e) {
        SqlExecuteStat.error(e);
        throw new DataAccessException(e);
    } finally {
        // 最终输出执行失效和错误日志
        SqlExecuteStat.destroy();
    }
}
Also used : Connection(java.sql.Connection) ArrayList(java.util.ArrayList) DataSourceCallbackHandler(org.sagacity.sqltoy.callback.DataSourceCallbackHandler) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) ShardingModel(org.sagacity.sqltoy.config.model.ShardingModel)

Aggregations

Connection (java.sql.Connection)40 DataSourceCallbackHandler (org.sagacity.sqltoy.callback.DataSourceCallbackHandler)40 DataAccessException (org.sagacity.sqltoy.exception.DataAccessException)24 ArrayList (java.util.ArrayList)23 SqlToyConfig (org.sagacity.sqltoy.config.model.SqlToyConfig)20 List (java.util.List)19 BaseException (org.sagacity.sqltoy.exception.BaseException)15 QueryResult (org.sagacity.sqltoy.model.QueryResult)14 ShardingModel (org.sagacity.sqltoy.config.model.ShardingModel)13 SqlToyResult (org.sagacity.sqltoy.config.model.SqlToyResult)12 QueryExecutorExtend (org.sagacity.sqltoy.model.inner.QueryExecutorExtend)9 SqlToyContext (org.sagacity.sqltoy.SqlToyContext)6 ParallelCallbackHandler (org.sagacity.sqltoy.callback.ParallelCallbackHandler)5 ShardingGroupModel (org.sagacity.sqltoy.model.ShardingGroupModel)5 ShardingModel (org.sagacity.sqltoy.model.ShardingModel)5 Serializable (java.io.Serializable)3 SqlParamsModel (org.sagacity.sqltoy.config.model.SqlParamsModel)3 Type (java.lang.reflect.Type)2 HashMap (java.util.HashMap)2 DataSource (javax.sql.DataSource)2