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();
}
}
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();
}
}
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();
}
}
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();
}
}
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();
}
}
Aggregations