use of org.sagacity.sqltoy.config.model.ShardingStrategyConfig 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());
// 主键值需要提前按照主键策略赋予(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.getName());
if (shardingStrategy == null)
throw new Exception("POJO 对象:" + entity.getClass().getName() + " Sharding DB Strategy:" + strategyConfig.getName() + " 未定义,请检查!");
IgnoreCaseLinkedMap<String, Object> valueMap = hashParams(strategyConfig.getAliasNames(), BeanUtil.reflectBeanToAry(entity, strategyConfig.getFields(), null, null));
ShardingDBModel dbModel = shardingStrategy.getShardingDB(sqlToyContext, entity.getClass(), entityMeta.getSchemaTable(), strategyConfig.getDecisionType(), valueMap);
shardingModel.setDataSourceName(dbModel.getDataSourceName());
if (dbModel.getDataSource() == null)
shardingModel.setDataSource(sqlToyContext.getDataSource(dbModel.getDataSourceName()));
else
shardingModel.setDataSource(dbModel.getDataSource());
}
// 分表策略
if (shardingConfig.getShardingTableStrategy() != null) {
strategyConfig = shardingConfig.getShardingTableStrategy();
shardingStrategy = sqlToyContext.getShardingStrategy(strategyConfig.getName());
if (shardingStrategy == null)
throw new Exception("POJO 对象:" + entity.getClass().getName() + " Sharding Table Strategy:" + strategyConfig.getName() + " 未定义,请检查!");
IgnoreCaseLinkedMap<String, Object> valueMap = hashParams(strategyConfig.getAliasNames(), BeanUtil.reflectBeanToAry(entity, strategyConfig.getFields(), null, null));
String tableName = shardingStrategy.getShardingTable(sqlToyContext, entity.getClass(), entityMeta.getSchemaTable(), strategyConfig.getDecisionType(), valueMap);
if (StringUtil.isNotBlank(tableName))
shardingModel.setTableName(tableName);
}
return shardingModel;
}
use of org.sagacity.sqltoy.config.model.ShardingStrategyConfig 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;
// 没有sharding配置,则作为单个分组返回
if (shardingConfig == null) {
Collection<ShardingGroupModel> result = new ArrayList<ShardingGroupModel>();
ShardingGroupModel model = new ShardingGroupModel();
shardingModel = new ShardingModel();
shardingModel.setDataSource(dataSource);
model.setShardingModel(shardingModel);
model.setEntities(entities);
result.add(model);
return result;
}
Class entityClass = entities.get(0).getClass();
String entityTable = entityMeta.getSchemaTable();
// 分库
boolean hasDB = false;
ShardingStrategy dbStrategy = null;
List<Object[]> shardingDBValues = null;
ShardingStrategyConfig dbConfig = shardingConfig.getShardingDBStrategy();
if (dbConfig != null) {
hasDB = true;
dbStrategy = sqlToyContext.getShardingStrategy(dbConfig.getName());
if (dbStrategy == null)
throw new Exception("POJO 对象:" + entityClass.getName() + " Sharding DB Strategy:" + dbConfig.getName() + " 未定义,请检查!");
shardingDBValues = BeanUtil.reflectBeansToInnerAry(entities, dbConfig.getFields(), null, null, false, 0);
}
// 分表
boolean hasTable = false;
ShardingStrategy tableStrategy = null;
ShardingStrategyConfig tableConfig = shardingConfig.getShardingTableStrategy();
List<Object[]> shardingTableValues = null;
if (tableConfig != null) {
hasTable = true;
tableStrategy = sqlToyContext.getShardingStrategy(tableConfig.getName());
if (tableStrategy == null)
throw new Exception("POJO 对象:" + entityClass.getName() + " Sharding Table Strategy:" + tableConfig.getName() + " 未定义,请检查!");
shardingTableValues = BeanUtil.reflectBeansToInnerAry(entities, tableConfig.getFields(), null, null, false, 0);
}
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);
}
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.getDataSource(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();
}
use of org.sagacity.sqltoy.config.model.ShardingStrategyConfig in project sagacity-sqltoy by chenrenfei.
the class QueryExecutorBuilder method wrapFullParamNames.
/**
* @TODO 构造sql实际使用到的全部参数名称,包括:cache-args(参数名-->别名,sql中用别名导致原参数名未被包含)、分库分表对应的参数名称
* @param paramNames
* @param extend
* @param sqlToyConfig
* @return
*/
private static String[] wrapFullParamNames(String[] paramNames, QueryExecutorExtend extend, SqlToyConfig sqlToyConfig) {
Set<String> keys = new HashSet<String>();
List<String> params = new ArrayList<String>();
String key;
// sql中自带的参数
if (paramNames != null && paramNames.length > 0) {
for (String item : paramNames) {
key = item.toLowerCase();
if (!keys.contains(key)) {
keys.add(key);
params.add(item);
}
}
}
// 分表参数(以QueryExecutor中指定的优先)
List<ShardingStrategyConfig> tableShardings = extend.tableShardings;
// 未指定则以sql中指定的分表策略为准
if (tableShardings == null || tableShardings.isEmpty()) {
tableShardings = sqlToyConfig.getTableShardings();
}
if (tableShardings != null && tableShardings.size() > 0) {
for (ShardingStrategyConfig shardingStrategy : tableShardings) {
if (shardingStrategy.getFields() != null) {
for (String item : shardingStrategy.getFields()) {
key = item.toLowerCase();
if (!keys.contains(key)) {
keys.add(key);
params.add(item);
}
}
}
}
}
// 分库参数
ShardingStrategyConfig dbSharding = extend.dbSharding;
if (dbSharding == null) {
dbSharding = sqlToyConfig.getDataSourceSharding();
}
if (dbSharding != null && dbSharding.getFields() != null) {
for (String item : dbSharding.getFields()) {
key = item.toLowerCase();
if (!keys.contains(key)) {
keys.add(key);
params.add(item);
}
}
}
if (params.isEmpty()) {
return null;
}
return params.toArray(new String[params.size()]);
}
use of org.sagacity.sqltoy.config.model.ShardingStrategyConfig in project sagacity-sqltoy by chenrenfei.
the class DialectUtils method getUnifyParamsNamedConfig.
/**
* @todo 统一将查询的sql参数由?形式变成:named形式(分页和查询随机记录时)
* @param sqlToyContext
* @param sqlToyConfig
* @param queryExecutor
* @param dialect
* @param wrapNamed 只在分页场景下需要将?模式传参统一成:name模式,便于跟后面分页startIndex和endIndex参数结合,从而利用sql预编译功能
* @return
* @throws Exception
*/
public static SqlToyConfig getUnifyParamsNamedConfig(SqlToyContext sqlToyContext, SqlToyConfig sqlToyConfig, QueryExecutor queryExecutor, String dialect, boolean wrapNamed) throws Exception {
QueryExecutorExtend extend = queryExecutor.getInnerModel();
// 本身就是:named参数形式或sql中没有任何参数
boolean isNamed = false;
// 在QueryExecutorBuilder中已经对wrappedParamNames做了判断赋值
if (!extend.wrappedParamNames) {
// sql中是否存在? 形式参数
boolean hasQuestArg = SqlConfigParseUtils.hasQuestMarkArgs(sqlToyConfig.getSql());
isNamed = ((extend.paramsName != null && extend.paramsName.length > 0) || !hasQuestArg);
}
// 以queryExecutor自定义的分表策略覆盖sql xml中定义的
List<ShardingStrategyConfig> tableShardings = sqlToyConfig.getTableShardings();
if (!extend.tableShardings.isEmpty()) {
tableShardings = extend.tableShardings;
}
// sql条件以:named形式、无分表、无扩展缓存翻译则不存在对SqlToyConfig 内容的修改,直接返回
if ((isNamed || !wrapNamed) && tableShardings.isEmpty() && extend.translates.isEmpty()) {
return sqlToyConfig;
}
// clone sqltoyConfig避免直接修改原始的sql配置对后续执行产生影响
SqlToyConfig result = sqlToyConfig.clone();
// 存在扩展的缓存翻译
if (!extend.translates.isEmpty()) {
result.getTranslateMap().putAll(extend.translates);
}
// ?传参且分页模式,原因是分页存在取count场景,在@fast()情况下无法断定paramValues的值跟?的参数对应关系
if (!isNamed && wrapNamed) {
SqlParamsModel sqlParams;
// 存在fast查询
if (result.isHasFast()) {
// @fast 前部分
String fastPreSql = SqlConfigParseUtils.clearDblQuestMark(result.getFastPreSql(null));
sqlParams = convertParamsToNamed(fastPreSql, 0);
fastPreSql = SqlConfigParseUtils.recoverDblQuestMark(sqlParams.getSql());
result.setFastPreSql(fastPreSql);
int index = sqlParams.getParamCnt();
// @fas() 中间部分
String fastSql = SqlConfigParseUtils.clearDblQuestMark(result.getFastSql(null));
sqlParams = convertParamsToNamed(fastSql, index);
fastSql = SqlConfigParseUtils.recoverDblQuestMark(sqlParams.getSql());
result.setFastSql(fastSql);
index = index + sqlParams.getParamCnt();
// 尾部
String tailSql = SqlConfigParseUtils.clearDblQuestMark(result.getFastTailSql(null));
sqlParams = convertParamsToNamed(tailSql, index);
tailSql = SqlConfigParseUtils.recoverDblQuestMark(sqlParams.getSql());
result.setFastTailSql(tailSql);
// 完整sql
result.setSql(fastPreSql.concat(" (").concat(fastSql).concat(") ").concat(tailSql));
// 构造对应?参数个数的:named模式参数名数组
String[] paramsName = new String[index];
for (int i = 0; i < index; i++) {
paramsName[i] = SqlToyConstants.DEFAULT_PARAM_NAME + (i + 1);
}
result.setParamsName(paramsName);
} else {
sqlParams = convertParamsToNamed(SqlConfigParseUtils.clearDblQuestMark(result.getSql(null)), 0);
result.setSql(SqlConfigParseUtils.recoverDblQuestMark(sqlParams.getSql()));
result.setParamsName(sqlParams.getParamsName());
}
// 自定义分页的count sql,一般无需定义
sqlParams = convertParamsToNamed(SqlConfigParseUtils.clearDblQuestMark(result.getCountSql(null)), 0);
result.setCountSql(SqlConfigParseUtils.recoverDblQuestMark(sqlParams.getSql()));
// 清空方言缓存
result.clearDialectSql();
SqlConfigParseUtils.processFastWith(result, dialect);
}
// sharding table 替换sql中的表名称
ShardingUtils.replaceShardingSqlToyConfig(sqlToyContext, result, tableShardings, dialect, extend.getTableShardingParamsName(sqlToyConfig), extend.getTableShardingParamsValue(sqlToyConfig));
return result;
}
use of org.sagacity.sqltoy.config.model.ShardingStrategyConfig in project sagacity-sqltoy by chenrenfei.
the class QueryExecutor method dbSharding.
/**
* @TODO 设置分库策略
* @param strategy
* @param paramNames
* @return
*/
public QueryExecutor dbSharding(String strategy, String... paramNames) {
ShardingStrategyConfig sharding = new ShardingStrategyConfig(0);
sharding.setStrategy(strategy);
sharding.setFields(paramNames);
sharding.setAliasNames(paramNames);
innerModel.dbSharding = sharding;
return this;
}
Aggregations