Search in sources :

Example 1 with ShardingStrategyConfig

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;
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) ShardingStrategy(org.sagacity.sqltoy.plugin.ShardingStrategy) ShardingConfig(org.sagacity.sqltoy.config.model.ShardingConfig) ShardingStrategyConfig(org.sagacity.sqltoy.config.model.ShardingStrategyConfig) ShardingDBModel(org.sagacity.sqltoy.model.ShardingDBModel) QueryShardingModel(org.sagacity.sqltoy.config.model.QueryShardingModel) ShardingModel(org.sagacity.sqltoy.model.ShardingModel)

Example 2 with ShardingStrategyConfig

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();
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ShardingDBModel(org.sagacity.sqltoy.model.ShardingDBModel) ShardingGroupModel(org.sagacity.sqltoy.model.ShardingGroupModel) ShardingStrategy(org.sagacity.sqltoy.plugin.ShardingStrategy) ShardingConfig(org.sagacity.sqltoy.config.model.ShardingConfig) ShardingStrategyConfig(org.sagacity.sqltoy.config.model.ShardingStrategyConfig) ArrayList(java.util.ArrayList) List(java.util.List) QueryShardingModel(org.sagacity.sqltoy.config.model.QueryShardingModel) ShardingModel(org.sagacity.sqltoy.model.ShardingModel)

Example 3 with ShardingStrategyConfig

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()]);
}
Also used : ShardingStrategyConfig(org.sagacity.sqltoy.config.model.ShardingStrategyConfig) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet)

Example 4 with ShardingStrategyConfig

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;
}
Also used : ShardingStrategyConfig(org.sagacity.sqltoy.config.model.ShardingStrategyConfig) SqlToyConfig(org.sagacity.sqltoy.config.model.SqlToyConfig) SqlParamsModel(org.sagacity.sqltoy.config.model.SqlParamsModel) QueryExecutorExtend(org.sagacity.sqltoy.model.inner.QueryExecutorExtend)

Example 5 with ShardingStrategyConfig

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;
}
Also used : ShardingStrategyConfig(org.sagacity.sqltoy.config.model.ShardingStrategyConfig)

Aggregations

ShardingStrategyConfig (org.sagacity.sqltoy.config.model.ShardingStrategyConfig)18 ArrayList (java.util.ArrayList)8 ShardingConfig (org.sagacity.sqltoy.config.model.ShardingConfig)5 HashSet (java.util.HashSet)4 HashMap (java.util.HashMap)3 EntityMeta (org.sagacity.sqltoy.config.model.EntityMeta)3 List (java.util.List)2 DataSource (javax.sql.DataSource)2 QueryShardingModel (org.sagacity.sqltoy.config.model.QueryShardingModel)2 ShardingDBModel (org.sagacity.sqltoy.config.model.ShardingDBModel)2 ShardingModel (org.sagacity.sqltoy.config.model.ShardingModel)2 SqlToyConfig (org.sagacity.sqltoy.config.model.SqlToyConfig)2 ShardingDBModel (org.sagacity.sqltoy.model.ShardingDBModel)2 ShardingModel (org.sagacity.sqltoy.model.ShardingModel)2 QueryExecutorExtend (org.sagacity.sqltoy.model.inner.QueryExecutorExtend)2 ShardingStrategy (org.sagacity.sqltoy.plugin.ShardingStrategy)2 Element (org.w3c.dom.Element)2 Entry (java.util.Map.Entry)1 Sharding (org.sagacity.sqltoy.config.annotation.Sharding)1 Strategy (org.sagacity.sqltoy.config.annotation.Strategy)1