use of org.sagacity.sqltoy.callback.DataSourceCallbackHandler in project sagacity-sqltoy by chenrenfei.
the class DialectFactory method updateFetch.
/**
* @todo 查询锁定记录,并进行修改
* @param sqlToyContext
* @param queryExecutor
* @param updateRowHandler
* @param dataSource
* @return
* @throws Exception
*/
public QueryResult updateFetch(final SqlToyContext sqlToyContext, final QueryExecutor queryExecutor, final UpdateRowHandler updateRowHandler, final DataSource dataSource) throws Exception {
final SqlToyConfig sqlToyConfig = sqlToyContext.getSqlToyConfig(queryExecutor.getSql(), SqlType.search);
try {
SqlExecuteStat.start(sqlToyConfig.getId(), "updateFetch", sqlToyConfig.isShowSql());
return (QueryResult) DataSourceUtils.processDataSource(sqlToyContext, ShardingUtils.getShardingDataSource(sqlToyContext, sqlToyConfig, queryExecutor, dataSource), new DataSourceCallbackHandler() {
public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
// 处理sql中的?为统一的:named形式
SqlToyConfig realSqlToyConfig = DialectUtils.getUnifyParamsNamedConfig(sqlToyContext, sqlToyConfig, queryExecutor, dialect, false);
SqlToyResult queryParam = SqlConfigParseUtils.processSql(realSqlToyConfig.getSql(), queryExecutor.getParamsName(realSqlToyConfig), queryExecutor.getParamsValue(realSqlToyConfig));
QueryResult queryResult = getDialectSqlWrapper(dbType).updateFetch(sqlToyContext, realSqlToyConfig, queryParam.getSql(), queryParam.getParamsValue(), updateRowHandler, conn);
if (queryExecutor.getResultType() != null) {
queryResult.setRows(ResultUtils.wrapQueryResult(queryResult.getRows(), ResultUtils.humpFieldNames(queryExecutor, queryResult.getLabelNames()), (Class) queryExecutor.getResultType()));
}
this.setResult(queryResult);
}
});
} catch (Exception e) {
SqlExecuteStat.error(e);
throw e;
} finally {
SqlExecuteStat.destroy();
}
}
use of org.sagacity.sqltoy.callback.DataSourceCallbackHandler in project sagacity-sqltoy by chenrenfei.
the class DialectFactory method batchUpdate.
/**
* @todo 批量执行sql修改或删除操作
* @param sqlToyContext
* @param sqlToyConfig
* @param dataSet 支持List<List>、List<Object[]>(sql中?传参)
* ;List<VO>、List<Map> 形式(sql中:paramName传参)
* @param batchSize
* @param reflectPropsHandler
* @param insertCallhandler 使用反调方式自己对rs进行处理
* @param autoCommit
* @param dataSource
* @return
*/
public Long batchUpdate(final SqlToyContext sqlToyContext, final SqlToyConfig sqlToyConfig, final List dataSet, final int batchSize, final ReflectPropsHandler reflectPropsHandler, final InsertRowCallbackHandler insertCallhandler, final Boolean autoCommit, final DataSource dataSource) {
// 首先合法性校验
if (dataSet == null || dataSet.isEmpty()) {
logger.warn("batchUpdate dataSet is null or empty,please check!");
return 0L;
}
try {
// 启动执行日志(会在threadlocal中创建一个当前执行信息,并建立一个唯一跟踪id)
SqlExecuteStat.start(sqlToyConfig.getId(), "batchUpdate:[" + dataSet.size() + "]条记录!", sqlToyConfig.isShowSql());
Long updateTotalCnt = (Long) DataSourceUtils.processDataSource(sqlToyContext, dataSource, new DataSourceCallbackHandler() {
@Override
public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
String realSql = sqlToyConfig.getSql(dialect);
Integer[] fieldTypes = null;
List values = dataSet;
// sql中存在:named参数模式,通过sql提取参数名称
if (sqlToyConfig.getParamsName() != null) {
// 替换sql中:name为?并提取参数名称归集成数组
SqlParamsModel sqlParamsModel = SqlConfigParseUtils.processNamedParamsQuery(realSql);
realSql = sqlParamsModel.getSql();
// update 2021-10-28 增加统一授权传参、根据insert、update 判断自动补充创建人、创建时间、修改人、修改时间等属性值的填充
ReflectPropsHandler realPropsHandler = DialectUtils.wrapReflectWithUnifyFields(realSql, reflectPropsHandler, sqlToyContext.getUnifyFieldsHandler());
values = BeanUtil.reflectBeansToList(dataSet, sqlParamsModel.getParamsName(), realPropsHandler);
fieldTypes = BeanUtil.matchMethodsType(dataSet.get(0).getClass(), sqlParamsModel.getParamsName());
}
// 做sql签名
realSql = SqlUtilsExt.signSql(realSql, dbType, sqlToyConfig);
SqlExecuteStat.showSql("批量sql执行", realSql, null);
this.setResult(SqlUtil.batchUpdateByJdbc(sqlToyContext.getTypeHandler(), realSql, values, batchSize, insertCallhandler, fieldTypes, autoCommit, conn, dbType));
}
});
// 输出执行结果更新记录量日志
SqlExecuteStat.debug("执行结果", "批量更新记录数量:{} 条!", updateTotalCnt);
return 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 getRandomResult.
/**
* @todo 取随机记录
* @param sqlToyContext
* @param queryExecutor
* @param sqlToyConfig
* @param randomCount
* @param dataSource
* @return
*/
public QueryResult getRandomResult(final SqlToyContext sqlToyContext, final QueryExecutor queryExecutor, final SqlToyConfig sqlToyConfig, final Double randomCount, final DataSource dataSource) {
final QueryExecutorExtend extend = queryExecutor.getInnerModel();
if (extend.sql == null) {
throw new IllegalArgumentException("getRandomResult operate sql is null!");
}
try {
Long startTime = System.currentTimeMillis();
// 规整查询参数名称和参数名称对应的值
QueryExecutorBuilder.initQueryExecutor(sqlToyContext, extend, sqlToyConfig, (randomCount < 1) ? true : false);
SqlExecuteStat.start(sqlToyConfig.getId(), "getRandomResult", 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, (randomCount < 1) ? true : false);
// 判断数据库是否支持取随机记录(只有informix和sybase不支持)
Long totalCount = null;
Long randomCnt;
// 记录数量大于1表示取随机记录数量
if (randomCount >= 1) {
randomCnt = randomCount.longValue();
} else // 按比例提取
{
// 提取总记录数
if (totalCount == null) {
totalCount = getCountBySql(sqlToyContext, realSqlToyConfig, queryExecutor, conn, dbType, dialect);
}
randomCnt = Double.valueOf(totalCount * randomCount.doubleValue()).longValue();
SqlExecuteStat.debug("过程提示", "按比例提取总记录数:{}条,需取随机记录:{}条!", totalCount, randomCnt);
// 如果总记录数不为零,randomCnt最小为1
if (totalCount >= 1 && randomCnt < 1) {
randomCnt = 1L;
}
}
QueryResult queryResult;
// 总记录数为零
if (totalCount != null && totalCount == 0) {
queryResult = new QueryResult();
queryResult.setRows(new ArrayList());
this.setResult(queryResult);
logger.warn("getRandom,total Records is zero,please check sql!sqlId={}", sqlToyConfig.getIdOrSql());
return;
}
queryResult = getDialectSqlWrapper(dbType).getRandomResult(sqlToyContext, realSqlToyConfig, queryExecutor, wrapDecryptHandler(sqlToyContext, extend.resultType), totalCount, randomCnt, conn, dbType, dialect, getFetchSize(extend.fetchSize), extend.maxRows);
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));
}
}
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 update.
/**
* @todo 修改单个对象
* @param sqlToyContext
* @param entity
* @param uniqueFields 唯一性索引字段
* @param forceUpdateFields
* @param cascade
* @param forceCascadeClass
* @param subTableForceUpdateProps
* @param dataSource
* @return
*/
public Long update(final SqlToyContext sqlToyContext, final Serializable entity, final String[] forceUpdateFields, final boolean cascade, final Class[] forceCascadeClass, final HashMap<Class, String[]> subTableForceUpdateProps, final DataSource dataSource) {
if (entity == null) {
logger.warn("update entity is null,please check!");
return 0L;
}
try {
SqlExecuteStat.start(BeanUtil.getEntityClass(entity.getClass()).getName(), "update", null);
final ShardingModel shardingModel = ShardingUtils.getSharding(sqlToyContext, entity, false, dataSource);
Long updateTotalCnt = (Long) DataSourceUtils.processDataSource(sqlToyContext, shardingModel.getDataSource(), new DataSourceCallbackHandler() {
@Override
public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
this.setResult(getDialectSqlWrapper(dbType).update(sqlToyContext, entity, forceUpdateFields, cascade, forceCascadeClass, subTableForceUpdateProps, conn, dbType, dialect, shardingModel.getTableName()));
}
});
SqlExecuteStat.debug("执行结果", "update操作影响记录量:{} 条!", updateTotalCnt);
return 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 executeSql.
/**
* @todo 执行sql修改性质的操作语句
* @param sqlToyContext
* @param sqlToyConfig
* @param queryExecutor
* @param paramsTypes
* @param autoCommit
* @param dataSource
* @return
*/
public Long executeSql(final SqlToyContext sqlToyContext, final SqlToyConfig sqlToyConfig, final QueryExecutor queryExecutor, final Integer[] paramsTypes, final Boolean autoCommit, final DataSource dataSource) {
try {
SqlExecuteStat.start(sqlToyConfig.getId(), "executeSql", sqlToyConfig.isShowSql());
// 将修改语句当做特殊的查询,其处理过程在交jdbc执行前完全一致
final QueryExecutorExtend extend = queryExecutor.getInnerModel();
// 组织参数和参数校验,但忽视数据权限数据的传参和校验
QueryExecutorBuilder.initQueryExecutor(sqlToyContext, extend, sqlToyConfig, false);
Long updateTotalCnt = (Long) DataSourceUtils.processDataSource(sqlToyContext, ShardingUtils.getShardingDataSource(sqlToyContext, sqlToyConfig, queryExecutor, dataSource), new DataSourceCallbackHandler() {
@Override
public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
// 进行sharding table替换
SqlToyConfig realSqlToyConfig = DialectUtils.getUnifyParamsNamedConfig(sqlToyContext, sqlToyConfig, queryExecutor, dialect, false);
SqlToyResult queryParam = SqlConfigParseUtils.processSql(realSqlToyConfig.getSql(dialect), extend.getParamsName(sqlToyConfig), extend.getParamsValue(sqlToyContext, realSqlToyConfig), dialect);
// 做sql签名
String executeSql = SqlUtilsExt.signSql(queryParam.getSql(), dbType, realSqlToyConfig);
this.setResult(SqlUtil.executeSql(sqlToyContext.getTypeHandler(), executeSql, queryParam.getParamsValue(), paramsTypes, conn, dbType, autoCommit, false));
}
});
SqlExecuteStat.debug("执行结果", "受影响记录数量:{} 条!", updateTotalCnt);
return updateTotalCnt;
} catch (Exception e) {
SqlExecuteStat.error(e);
throw new DataAccessException(e);
} finally {
SqlExecuteStat.destroy();
}
}
Aggregations