use of org.sagacity.sqltoy.config.model.ShardingModel in project sagacity-sqltoy by chenrenfei.
the class DialectFactory method updateSaveFetch.
/**
* @TODO 适用于库存台账、客户资金账强事务高并发场景,一次数据库交互实现:1、锁查询;2、记录存在则修改;3、记录不存在则执行insert;4、返回修改或插入的记录信息
* @param sqlToyContext
* @param entity
* @param updateRowHandler
* @param uniqueProps 空则表示根据主键查询
* @param dataSource
* @return
*/
public Serializable updateSaveFetch(final SqlToyContext sqlToyContext, final Serializable entity, final UpdateRowHandler updateRowHandler, final String[] uniqueProps, final DataSource dataSource) {
if (entity == null || updateRowHandler == null) {
logger.warn("updateSaveFetch entity or updateRowHandler is null,please check!");
return null;
}
try {
SqlExecuteStat.start(BeanUtil.getEntityClass(entity.getClass()).getName(), "updateSaveFetch", null);
final ShardingModel shardingModel = ShardingUtils.getSharding(sqlToyContext, entity, false, dataSource);
Serializable result = (Serializable) DataSourceUtils.processDataSource(sqlToyContext, shardingModel.getDataSource(), new DataSourceCallbackHandler() {
@Override
public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
this.setResult(getDialectSqlWrapper(dbType).updateSaveFetch(sqlToyContext, entity, updateRowHandler, uniqueProps, conn, dbType, dialect, shardingModel.getTableName()));
}
});
return result;
} catch (Exception e) {
SqlExecuteStat.error(e);
throw new DataAccessException(e);
} finally {
SqlExecuteStat.destroy();
}
}
use of org.sagacity.sqltoy.config.model.ShardingModel 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.config.model.ShardingModel 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();
}
}
use of org.sagacity.sqltoy.config.model.ShardingModel in project sagacity-sqltoy by chenrenfei.
the class ShardingUtils method getSharding.
/**
* @todo 单个对象sharding策略处理,适用于load、save、update、delete单对象操作
* @param sqlToyContext
* @param entity
* @param wrapIdValue
* @param dataSource
* @return
* @throws Exception
*/
public static ShardingModel getSharding(SqlToyContext sqlToyContext, Serializable entity, boolean wrapIdValue, DataSource dataSource) throws Exception {
ShardingModel shardingModel = new ShardingModel();
shardingModel.setDataSource(dataSource);
EntityMeta entityMeta = sqlToyContext.getEntityMeta(entity.getClass());
shardingModel.setTableName(entityMeta.getTableName());
// 主键值需要提前按照主键策略赋予(sequence 和assign模式的不会实际执行赋值)
if (wrapIdValue) {
assignPK(sqlToyContext, entityMeta, entity);
}
ShardingConfig shardingConfig = entityMeta.getShardingConfig();
if (shardingConfig == null) {
return shardingModel;
}
ShardingStrategy shardingStrategy;
ShardingStrategyConfig strategyConfig;
// 分库策略处理
if (shardingConfig.getShardingDBStrategy() != null) {
strategyConfig = shardingConfig.getShardingDBStrategy();
shardingStrategy = sqlToyContext.getShardingStrategy(strategyConfig.getStrategy());
if (shardingStrategy == null) {
throw new IllegalArgumentException("POJO 对象:" + entity.getClass().getName() + " Sharding DB Strategy:" + strategyConfig.getStrategy() + " 未定义,请检查!");
}
IgnoreCaseLinkedMap<String, Object> valueMap = hashParams(strategyConfig.getAliasNames(), BeanUtil.reflectBeanToAry(entity, strategyConfig.getFields()));
ShardingDBModel dbModel = shardingStrategy.getShardingDB(sqlToyContext, entity.getClass(), entityMeta.getTableName(), strategyConfig.getDecisionType(), valueMap);
shardingModel.setDataSourceName(dbModel.getDataSourceName());
if (dbModel.getDataSource() == null) {
shardingModel.setDataSource(sqlToyContext.getDataSourceBean(dbModel.getDataSourceName()));
} else {
shardingModel.setDataSource(dbModel.getDataSource());
}
}
// 分表策略
if (shardingConfig.getShardingTableStrategy() != null) {
strategyConfig = shardingConfig.getShardingTableStrategy();
shardingStrategy = sqlToyContext.getShardingStrategy(strategyConfig.getStrategy());
if (shardingStrategy == null) {
throw new IllegalArgumentException("POJO 对象:" + entity.getClass().getName() + " Sharding Table Strategy:" + strategyConfig.getStrategy() + " 未定义,请检查!");
}
IgnoreCaseLinkedMap<String, Object> valueMap = hashParams(strategyConfig.getAliasNames(), BeanUtil.reflectBeanToAry(entity, strategyConfig.getFields()));
String tableName = shardingStrategy.getShardingTable(sqlToyContext, entity.getClass(), entityMeta.getTableName(), strategyConfig.getDecisionType(), valueMap);
if (StringUtil.isNotBlank(tableName)) {
shardingModel.setTableName(tableName);
}
}
return shardingModel;
}
use of org.sagacity.sqltoy.config.model.ShardingModel in project sagacity-sqltoy by chenrenfei.
the class ShardingUtils method groupShardings.
/**
* @todo 批量sharding策略处理
* @param sqlToyContext
* @param entities
* @param entityMeta
* @param dataSource
* @return
* @throws Exception
*/
public static Collection<ShardingGroupModel> groupShardings(SqlToyContext sqlToyContext, List<?> entities, EntityMeta entityMeta, DataSource dataSource) throws Exception {
ShardingConfig shardingConfig = entityMeta.getShardingConfig();
ShardingModel shardingModel = null;
String entityTable = entityMeta.getTableName();
// 没有sharding配置,则作为单个分组返回
if (shardingConfig == null) {
Collection<ShardingGroupModel> result = new ArrayList<ShardingGroupModel>();
ShardingGroupModel model = new ShardingGroupModel();
shardingModel = new ShardingModel();
shardingModel.setDataSource(dataSource);
shardingModel.setTableName(entityTable);
model.setShardingModel(shardingModel);
model.setEntities(entities);
result.add(model);
return result;
}
Class entityClass = entityMeta.getEntityClass();
// 分库
boolean hasDB = false;
ShardingStrategy dbStrategy = null;
List<Object[]> shardingDBValues = null;
ShardingStrategyConfig dbConfig = shardingConfig.getShardingDBStrategy();
if (dbConfig != null) {
hasDB = true;
dbStrategy = sqlToyContext.getShardingStrategy(dbConfig.getStrategy());
if (dbStrategy == null) {
throw new IllegalArgumentException("POJO 对象:" + entityClass.getName() + " Sharding DB Strategy:" + dbConfig.getStrategy() + " 未定义,请检查!");
}
shardingDBValues = BeanUtil.reflectBeansToInnerAry(entities, dbConfig.getFields(), null, null);
}
// 分表
boolean hasTable = false;
ShardingStrategy tableStrategy = null;
ShardingStrategyConfig tableConfig = shardingConfig.getShardingTableStrategy();
List<Object[]> shardingTableValues = null;
if (tableConfig != null) {
hasTable = true;
tableStrategy = sqlToyContext.getShardingStrategy(tableConfig.getStrategy());
if (tableStrategy == null) {
throw new IllegalArgumentException("POJO 对象:" + entityClass.getName() + " Sharding Table Strategy:" + tableConfig.getStrategy() + " 未定义,请检查!");
}
shardingTableValues = BeanUtil.reflectBeansToInnerAry(entities, tableConfig.getFields(), null, null);
}
Map<String, ShardingGroupModel> shardingGroupMaps = new HashMap<String, ShardingGroupModel>();
IgnoreCaseLinkedMap<String, Object> valueMap;
ShardingDBModel shardingDBModel = null;
// 数据分组key(dataSourceName+tableName)
String dataGroupKey;
String tableName = null;
String dataSourceName = null;
for (int i = 0; i < entities.size(); i++) {
// 分库
if (hasDB) {
valueMap = hashParams(dbConfig.getAliasNames(), shardingDBValues.get(i));
shardingDBModel = dbStrategy.getShardingDB(sqlToyContext, entityClass, entityTable, dbConfig.getDecisionType(), valueMap);
dataSourceName = shardingDBModel.getDataSourceName();
}
// 分表
if (hasTable) {
valueMap = hashParams(tableConfig.getAliasNames(), shardingTableValues.get(i));
tableName = tableStrategy.getShardingTable(sqlToyContext, entityClass, entityTable, tableConfig.getDecisionType(), valueMap);
}
// 分组key
dataGroupKey = dataSourceName + tableName;
// 归并到相同分组
if (shardingGroupMaps.containsKey(dataGroupKey)) {
shardingGroupMaps.get(dataGroupKey).getEntities().add(entities.get(i));
} else {
// 不同分组
ShardingGroupModel groupModel = new ShardingGroupModel();
groupModel.setKey(dataGroupKey);
// 创建数据分组集合
List items = new ArrayList();
items.add(entities.get(i));
groupModel.setEntities(items);
shardingModel = new ShardingModel();
// 分库,设置分组对应的数据库
if (hasDB) {
shardingModel.setDataSourceName(dataSourceName);
if (shardingDBModel.getDataSource() == null) {
shardingModel.setDataSource(sqlToyContext.getDataSourceBean(shardingDBModel.getDataSourceName()));
} else {
shardingModel.setDataSource(shardingDBModel.getDataSource());
}
} else {
shardingModel.setDataSource(dataSource);
}
// 分表,设置表名
if (hasTable && StringUtil.isNotBlank(tableName)) {
shardingModel.setTableName(tableName);
}
groupModel.setShardingModel(shardingModel);
shardingGroupMaps.put(dataGroupKey, groupModel);
}
}
return shardingGroupMaps.values();
}
Aggregations