use of org.sagacity.sqltoy.callback.DataSourceCallbackHandler in project sagacity-sqltoy by chenrenfei.
the class DialectFactory method saveAll.
/**
* @todo 批量保存
* @param sqlToyContext
* @param entities
* @param batchSize
* @param reflectPropsHandler
* @param dataSource
* @param autoCommit
*/
public Long saveAll(final SqlToyContext sqlToyContext, final List<?> entities, final int batchSize, final ReflectPropsHandler reflectPropsHandler, final DataSource dataSource, final Boolean autoCommit) {
if (entities == null || entities.isEmpty()) {
logger.warn("saveAll entities is null or empty,please check!");
return 0L;
}
try {
SqlExecuteStat.start(BeanUtil.getEntityClass(entities.get(0).getClass()).getName(), "saveAll:[" + 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).saveAll(context, batchModel.getEntities(), batchSize, reflectPropsHandler, 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 findByQuery.
/**
* @todo 查询符合条件的数据集合
* @param sqlToyContext
* @param queryExecutor
* @param sqlToyConfig
* @param lockMode
* @param dataSource
* @return
*/
public QueryResult findByQuery(final SqlToyContext sqlToyContext, final QueryExecutor queryExecutor, final SqlToyConfig sqlToyConfig, final LockMode lockMode, final DataSource dataSource) {
final QueryExecutorExtend extend = queryExecutor.getInnerModel();
// 合法校验
if (StringUtil.isBlank(extend.sql)) {
throw new IllegalArgumentException("findByQuery operate sql is null!");
}
try {
Long startTime = System.currentTimeMillis();
// 规整查询参数名称和参数名称对应的值
QueryExecutorBuilder.initQueryExecutor(sqlToyContext, extend, sqlToyConfig, false);
SqlExecuteStat.start(sqlToyConfig.getId(), "findByQuery", 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);
// 通过参数处理最终的sql和参数值
SqlToyResult queryParam = SqlConfigParseUtils.processSql(realSqlToyConfig.getSql(dialect), extend.getParamsName(realSqlToyConfig), extend.getParamsValue(sqlToyContext, realSqlToyConfig), dialect);
QueryResult queryResult = getDialectSqlWrapper(dbType).findBySql(sqlToyContext, realSqlToyConfig, queryParam.getSql(), queryParam.getParamsValue(), extend.rowCallbackHandler, wrapDecryptHandler(sqlToyContext, extend.resultType), conn, lockMode, 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 saveAllIgnoreExist.
/**
* @todo 批量保存数据,当已经存在的时候忽视掉
* @param sqlToyContext
* @param entities
* @param batchSize
* @param reflectPropsHandler
* @param dataSource
* @param autoCommit
*/
public Long saveAllIgnoreExist(final SqlToyContext sqlToyContext, final List<?> entities, final int batchSize, final ReflectPropsHandler reflectPropsHandler, final DataSource dataSource, final Boolean autoCommit) {
if (entities == null || entities.isEmpty()) {
logger.warn("saveAllIgnoreExist entities is null or empty,please check!");
return 0L;
}
try {
SqlExecuteStat.start(BeanUtil.getEntityClass(entities.get(0).getClass()).getName(), "saveAllNotExist:[" + 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).saveAllIgnoreExist(context, batchModel.getEntities(), batchSize, reflectPropsHandler, 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 updateFetch.
/**
* @todo 查询锁定记录,并进行修改
* @param sqlToyContext
* @param queryExecutor
* @param sqlToyConfig
* @param updateRowHandler
* @param dataSource
* @return
*/
public QueryResult updateFetch(final SqlToyContext sqlToyContext, final QueryExecutor queryExecutor, final SqlToyConfig sqlToyConfig, final UpdateRowHandler updateRowHandler, final DataSource dataSource) {
final QueryExecutorExtend extend = queryExecutor.getInnerModel();
try {
Long startTime = System.currentTimeMillis();
SqlExecuteStat.start(sqlToyConfig.getId(), "updateFetch", sqlToyConfig.isShowSql());
// 组织参数和参数校验,但忽视数据权限数据的传参和校验
QueryExecutorBuilder.initQueryExecutor(sqlToyContext, extend, sqlToyConfig, false);
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形式
SqlToyConfig realSqlToyConfig = DialectUtils.getUnifyParamsNamedConfig(sqlToyContext, sqlToyConfig, queryExecutor, dialect, false);
SqlToyResult queryParam = SqlConfigParseUtils.processSql(realSqlToyConfig.getSql(dialect), extend.getParamsName(realSqlToyConfig), extend.getParamsValue(sqlToyContext, realSqlToyConfig), dialect);
QueryResult queryResult = getDialectSqlWrapper(dbType).updateFetch(sqlToyContext, realSqlToyConfig, queryParam.getSql(), queryParam.getParamsValue(), updateRowHandler, conn, dbType, dialect, (extend.lockMode == null) ? LockMode.UPGRADE : extend.lockMode, getFetchSize(extend.fetchSize), extend.maxRows);
if (extend.resultType != null) {
queryResult.setRows(ResultUtils.wrapQueryResult(sqlToyContext, queryResult.getRows(), queryResult.getLabelNames(), (Class) extend.resultType, false, 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 wrapTreeTableRoute.
/**
* @todo 构造树形表的节点路径、节点层级、节点类别(是否叶子节点)
* @param sqlToyContext
* @param treeModel
* @param dataSource
* @return
*/
public boolean wrapTreeTableRoute(final SqlToyContext sqlToyContext, final TreeTableModel treeModel, final DataSource dataSource) {
if (treeModel == null || StringUtil.isBlank(treeModel.getPidField())) {
throw new IllegalArgumentException("请检查pidField赋值是否正确!");
}
if (StringUtil.isBlank(treeModel.getLeafField()) || StringUtil.isBlank(treeModel.getNodeRouteField()) || StringUtil.isBlank(treeModel.getNodeLevelField())) {
throw new IllegalArgumentException("请检查isLeafField\nodeRouteField\nodeLevelField 赋值是否正确!");
}
try {
if (null != treeModel.getEntity()) {
EntityMeta entityMeta = null;
if (treeModel.getEntity() instanceof Type) {
entityMeta = sqlToyContext.getEntityMeta((Class) treeModel.getEntity());
} else {
entityMeta = sqlToyContext.getEntityMeta(treeModel.getEntity().getClass());
}
// 兼容填写fieldName,统一转化为columnName
// pid
String columnName = entityMeta.getColumnName(treeModel.getPidField());
if (columnName != null) {
treeModel.pidField(columnName);
}
// leafField
columnName = entityMeta.getColumnName(treeModel.getLeafField());
if (columnName != null) {
treeModel.isLeafField(columnName);
}
// nodeLevel
columnName = entityMeta.getColumnName(treeModel.getNodeLevelField());
if (columnName != null) {
treeModel.nodeLevelField(columnName);
}
// nodeRoute
columnName = entityMeta.getColumnName(treeModel.getNodeRouteField());
if (columnName != null) {
treeModel.nodeRouteField(columnName);
}
HashMap<String, String> columnMap = new HashMap<String, String>();
for (FieldMeta column : entityMeta.getFieldsMeta().values()) {
columnMap.put(column.getColumnName().toUpperCase(), "");
}
if (!columnMap.containsKey(treeModel.getNodeRouteField().toUpperCase())) {
throw new IllegalArgumentException("树形表:节点路径字段名称:" + treeModel.getNodeRouteField() + "不正确,请检查!");
}
if (!columnMap.containsKey(treeModel.getLeafField().toUpperCase())) {
throw new IllegalArgumentException("树形表:是否叶子节点字段名称:" + treeModel.getLeafField() + "不正确,请检查!");
}
if (!columnMap.containsKey(treeModel.getNodeLevelField().toUpperCase())) {
throw new IllegalArgumentException("树形表:节点等级字段名称:" + treeModel.getNodeLevelField() + "不正确,请检查!");
}
FieldMeta idMeta = (FieldMeta) entityMeta.getFieldMeta(entityMeta.getIdArray()[0]);
// 如未定义则使用主键(update 2020-10-16)
if (StringUtil.isBlank(treeModel.getIdField())) {
treeModel.idField(idMeta.getColumnName());
} else {
// 别名转换
columnName = entityMeta.getColumnName(treeModel.getIdField());
if (columnName != null) {
treeModel.idField(columnName);
}
}
if (StringUtil.isBlank(treeModel.getTableName())) {
treeModel.table(entityMeta.getSchemaTable(null, null));
}
// 通过实体对象取值给rootId和idValue赋值
if (!(treeModel.getEntity() instanceof Type)) {
// update 2020-10-19 从手工设定的字段中取值(原本从主键中取值)
if (null == treeModel.getRootId()) {
Object pidValue = BeanUtil.getProperty(treeModel.getEntity(), StringUtil.toHumpStr(treeModel.getPidField(), false));
treeModel.rootId(pidValue);
}
if (null == treeModel.getIdValue()) {
Object idValue = BeanUtil.getProperty(treeModel.getEntity(), StringUtil.toHumpStr(treeModel.getIdField(), false));
treeModel.setIdValue(idValue);
}
}
// 类型,默认值为false
if (idMeta.getType() == java.sql.Types.INTEGER || idMeta.getType() == java.sql.Types.DECIMAL || idMeta.getType() == java.sql.Types.DOUBLE || idMeta.getType() == java.sql.Types.FLOAT || idMeta.getType() == java.sql.Types.NUMERIC) {
treeModel.idTypeIsChar(false);
// update 2016-12-05 节点路径默认采取主键值直接拼接,更加直观科学
// treeModel.setAppendZero(true);
} else if (idMeta.getType() == java.sql.Types.VARCHAR || idMeta.getType() == java.sql.Types.CHAR) {
treeModel.idTypeIsChar(true);
}
}
SqlExecuteStat.start(treeModel.getTableName(), "wrapTreeTableRoute", true);
return (Boolean) DataSourceUtils.processDataSource(sqlToyContext, dataSource, new DataSourceCallbackHandler() {
@Override
public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
this.setResult(SqlUtil.wrapTreeTableRoute(sqlToyContext.getTypeHandler(), treeModel, conn, dbType));
}
});
} catch (Exception e) {
logger.error("封装树形表节点路径操作:wrapTreeTableRoute发生错误,{}", e.getMessage());
e.printStackTrace();
throw new DataAccessException(e);
} finally {
SqlExecuteStat.destroy();
}
}
Aggregations