wangwangwangBoy opened a new issue #12703:
URL: https://github.com/apache/shardingsphere/issues/12703


   ##### As the title, the Spring boot project uses Java for sharding-jdbc 
configuration, and encountered this error when starting.
   
   ##### Springboot main class:
   
   ```java
   
   import com.netflix.zuul.ZuulFilter;
   import org.springframework.boot.SpringApplication;
   import org.springframework.boot.autoconfigure.SpringBootApplication;
   import 
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration;
   import org.springframework.boot.web.servlet.ServletComponentScan;
   import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
   import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
   import 
org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapper;
   import org.springframework.cloud.openfeign.EnableFeignClients;
   import org.springframework.context.annotation.Bean;
   import 
org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
   
   @EnableZuulProxy
   @SpringBootApplication( scanBasePackageClasses = {GateWayApplication.class,
                ApplicationContextProvider.class})
   @EnableEurekaClient 
   @ServletComponentScan
   @EnableRedisHttpSession
   public class GateWayApplication {
        public static void main(String[] args) {
                SpringApplication.run(GateWayApplication.class, args);
        }
   
        @Bean
        public PatternServiceRouteMapper serviceRouteMapper() {
                return new 
PatternServiceRouteMapper("(?<name>^.+)-(?<version>.+$)", "${name}/${version}");
        }
   
        
       @Bean
       public ZuulFilter ProvideFilter(){
           return new ProvideFilter();
       }
        @Bean
        public RedisService redisService(){
                return new RedisService();
        }
        @Bean
        public FeignInterceptor feignInterceptor(){
                return new FeignInterceptor();
        }
   
   
   }
   
   ```
   
   
   
   ##### My main configuration is as follows:
   
   ```java
   
   import com.alibaba.druid.filter.Filter;
   import com.alibaba.druid.pool.DruidDataSource;
   import com.alibaba.druid.wall.WallConfig;
   import com.alibaba.druid.wall.WallFilter;
   import java.sql.SQLException;
   import java.util.ArrayList;
   import java.util.Collections;
   import java.util.HashMap;
   import java.util.List;
   import java.util.Map;
   import java.util.Properties;
   import javax.sql.DataSource;
   import org.apache.shardingsphere.driver.api.ShardingSphereDataSourceFactory;
   import 
org.apache.shardingsphere.infra.config.algorithm.ShardingSphereAlgorithmConfiguration;
   import 
org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration;
   import 
org.apache.shardingsphere.sharding.api.config.rule.ShardingTableRuleConfiguration;
   import 
org.apache.shardingsphere.sharding.api.config.strategy.keygen.KeyGenerateStrategyConfiguration;
   import 
org.apache.shardingsphere.sharding.api.config.strategy.sharding.StandardShardingStrategyConfiguration;
   import org.springframework.boot.context.properties.ConfigurationProperties;
   import org.springframework.context.annotation.Bean;
   import org.springframework.context.annotation.Configuration;
   import org.springframework.context.annotation.Primary;
   import org.springframework.jdbc.core.JdbcTemplate;
   import org.springframework.jdbc.datasource.DataSourceTransactionManager;
   
   
   @Configuration
   public class ShardingConfig {
   
   
       private final String DEVICE_LOGICAL_TABLE = 
"environment_supervise_device_data";
   
       private final String AI_LOGICAL_TABLE = "ai_supervise_device_data";
   
   
       private static final String LARGE_PROJECT_DEPARTMENT = 
"large_project_department";
   
       private static final String TABLE_RULE = "table_rule";
   
       private static final String DATABASE_RULE = "database_rule";
   
       public static final String DATABASE_SHARDING_ALGORITHM_NAME = 
"dataBaseShardingAlgorithmNameCreateDate";
       public static final String TABLE_SHARDING_ALGORITHM_NAME = 
"tableShardingAlgorithmNameCreateDate";
   
      
       private final String TABLE_SHARDING_COLUMN = "create_date";
   
       @Bean
       @Primary
       @ConfigurationProperties(prefix = "spring.datasource")
       public DataSource getDruidDataSource() {
           DruidDataSource druidDataSource = new DruidDataSource();
           List<Filter> filterList = new ArrayList<>();
           filterList.add(wallFilter());
           druidDataSource.setProxyFilters(filterList);
           return druidDataSource;
       }
   
   
       @Bean()
       public DataSource dataSource() throws SQLException {
           Map<String, DataSource> dataSourceMap = new HashMap<>(0);
           dataSourceMap.put(LARGE_PROJECT_DEPARTMENT, createDataSource());
           ShardingTableRuleConfiguration deviceDataRuleConfiguration = 
getTableRuleConfiguration(DEVICE_LOGICAL_TABLE);
           ShardingTableRuleConfiguration aiDataRuleConfiguration = 
getTableRuleConfiguration(AI_LOGICAL_TABLE);
   
           Properties properties = new Properties();
           properties.setProperty("sql.show", "true");
   
           ShardingRuleConfiguration shardingRuleConfiguration = new 
ShardingRuleConfiguration();
           
shardingRuleConfiguration.getTables().add(deviceDataRuleConfiguration);
           shardingRuleConfiguration.getTables().add(aiDataRuleConfiguration);
   
           shardingRuleConfiguration.setDefaultDatabaseShardingStrategy(
                   new 
StandardShardingStrategyConfiguration(TABLE_SHARDING_COLUMN, 
DATABASE_SHARDING_ALGORITHM_NAME));
           shardingRuleConfiguration.setDefaultTableShardingStrategy(
                   new 
StandardShardingStrategyConfiguration(TABLE_SHARDING_COLUMN, 
TABLE_SHARDING_ALGORITHM_NAME));
   
           shardingRuleConfiguration.getShardingAlgorithms()
                   .put(DATABASE_SHARDING_ALGORITHM_NAME,
                           new 
ShardingSphereAlgorithmConfiguration(DatabaseShardingAlgorithm.DATABASE_SHARDING_ALGORITHM,
                                   properties));
           shardingRuleConfiguration.getShardingAlgorithms()
                   .put(TABLE_SHARDING_ALGORITHM_NAME,
                           new 
ShardingSphereAlgorithmConfiguration(TableShardingAlgorithm.TABLE_SHARDING_ALGORITHM,
                                   properties));
           shardingRuleConfiguration.getKeyGenerators()
                   .put("snowflake", new 
ShardingSphereAlgorithmConfiguration("SNOWFLAKE", properties));
   
           
           return ShardingSphereDataSourceFactory
                   .createDataSource(dataSourceMap, 
Collections.singleton(shardingRuleConfiguration), properties);
   
       }
   
       @Bean
       public DataSourceTransactionManager dataSourceTransactionManager() {
           return new DataSourceTransactionManager(getDruidDataSource());
       }
   
       @Bean
       public JdbcTemplate jdbcTemplate() {
           return new JdbcTemplate(getDruidDataSource());
       }
   
       private DataSource createDataSource() {
           DruidDataSource dataSource = (DruidDataSource) getDruidDataSource();
           return dataSource;
       }
   
       private ShardingTableRuleConfiguration getTableRuleConfiguration(String 
tableName) {
           KeyGenerateStrategyConfiguration keyGeneratorConfiguration = new 
KeyGenerateStrategyConfiguration("id",
                   "SNOWFLAKE");
           ShardingTableRuleConfiguration deviceDataRuleConfiguration = new 
ShardingTableRuleConfiguration(tableName,
                   LARGE_PROJECT_DEPARTMENT + "." + tableName + 
"_20$->{21..22}0$->{1..9}" + "," +
                           LARGE_PROJECT_DEPARTMENT + "." + tableName + 
"_20$->{21..22}$->{11..12}");
           deviceDataRuleConfiguration.setDatabaseShardingStrategy(
                   new 
StandardShardingStrategyConfiguration(TABLE_SHARDING_COLUMN, DATABASE_RULE));
           deviceDataRuleConfiguration.setTableShardingStrategy(
                   new 
StandardShardingStrategyConfiguration(TABLE_SHARDING_COLUMN, TABLE_RULE));
           
deviceDataRuleConfiguration.setKeyGenerateStrategy(keyGeneratorConfiguration);
           return deviceDataRuleConfiguration;
       }
   
       @Bean
       public WallFilter wallFilter() {
           WallFilter wallFilter = new WallFilter();
           wallFilter.setConfig(wallConfig());
           return wallFilter;
       }
   
       @Bean
       public WallConfig wallConfig() {
           WallConfig config = new WallConfig();
           config.setMultiStatementAllow(true);
           config.setNoneBaseStatementAllow(true);
           return config;
       }
   }
   
   ```
   
   ##### The table fragmentation algorithm is configured as follows:
   
   ```java
   
   import com.google.common.collect.Range;
   import java.sql.SQLException;
   import java.util.ArrayList;
   import java.util.Collection;
   import java.util.Date;
   import java.util.List;
   import java.util.Optional;
   import javax.sql.DataSource;
   import org.apache.commons.collections4.CollectionUtils;
   import 
org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
   import 
org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
   import 
org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
   
   
   public class TableShardingAlgorithm implements 
StandardShardingAlgorithm<Date> {
   
       public static final String TABLE_SHARDING_ALGORITHM = 
"tableShardingAlgorithm";
   
       private AutoCreateTableConfig autoCreateTableConfig = new 
AutoCreateTableConfig();
   
       @Override
       public void init() {
   
       }
   
       @Override
       public String getType() {
           return TABLE_SHARDING_ALGORITHM;
       }
   
      
       @Override
       public String doSharding(Collection<String> availableTargetNames, 
PreciseShardingValue<Date> shardingValue) {
           long value = shardingValue.getValue().getTime();
           if (value <= 0) {
               throw new UnsupportedOperationException("preciseShardingValue is 
null");
           }
   
           String yearJoinMonthStr = 
DateUtil.getYearJoinMonthByMillisecond(value);
           Optional<String> optional = availableTargetNames.parallelStream()
                   .filter(item -> item.endsWith(yearJoinMonthStr))
                   .findAny();
           if (optional.isPresent()) {
               judgeTable(optional.get());
               return optional.get();
           }
           throw new UnsupportedOperationException("No available tables 
according input time:" + yearJoinMonthStr);
       }
   
   
   
       @Override
       public Collection<String> doSharding(Collection<String> 
availableTargetNames,
               RangeShardingValue<Date> rangeShardingValue) {
           Range<Date> range = rangeShardingValue.getValueRange();
           long startMillisecond = range.lowerEndpoint().getTime();
           long endMillisecond = range.upperEndpoint().getTime();
   
           // 起始年和结束年
           int startYear = 
Integer.parseInt(DateUtil.getYearByMillisecond(startMillisecond));
           int endYear = 
Integer.parseInt(DateUtil.getYearByMillisecond(endMillisecond));
           // 起始月和结束月
           int startMonth = 
Integer.parseInt(DateUtil.getMonthByMillisecond(startMillisecond));
           int endMonth = 
Integer.parseInt(DateUtil.getMonthByMillisecond(endMillisecond));
   
           int startYearJoinMonth = 
Integer.parseInt(DateUtil.getYearJoinMonthByMillisecond(startMillisecond));
           int endYearJoinMonth = 
Integer.parseInt(DateUtil.getYearJoinMonthByMillisecond(endMillisecond));
           List<String> result = startYear == endYear ? theSameYear(startYear, 
startMonth, endMonth, availableTargetNames)
                   : differentYear(startYear, endYear, startMonth, endMonth, 
startYearJoinMonth, endYearJoinMonth,
                           availableTargetNames);
           return result;
       }
   
   
       private List<String> theSameYear(int startYear, int startMonth, int 
endMonth, Collection<String> availableTargetNames) {
           return startMonth == endMonth ? theSameMonth(startYear, startMonth, 
availableTargetNames)
                   : differentMonth(startYear, startMonth, endMonth, 
availableTargetNames);
       }
   
   
       private List<String> theSameMonth(int startYear,int startMonth, 
Collection<String> availableTargetNames) {
           List<String> result = new ArrayList<>();
           String startMonthStr = String.valueOf(startMonth);
           if (startMonthStr.length() == 1) {
               startMonthStr = "0" + startMonthStr;
           }
           String condition = startYear + startMonthStr;
           for (String availableTargetName : availableTargetNames) {
               if (availableTargetName.endsWith(condition)) {
                   result.add(availableTargetName);
               }
           }
           return result;
       }
   
     
       private List<String> differentMonth(int startYear,int startMonth, int 
endMonth, Collection<String> availableTargetNames) {
           List<String> result = new ArrayList<>();
           for (String availableTargetName : availableTargetNames) {
               for (int i = startMonth; i <= endMonth; i++) {
                   String monthStr = String.valueOf(i);
                   if (monthStr.length() == 1) {
                       monthStr = "0" + monthStr;
                   }
                   if (availableTargetName.endsWith(startYear + monthStr)) {
                       result.add(availableTargetName);
                   }
               }
           }
           return result;
       }
   
       private List<String> differentYear(int startYear, int endYear, int 
startMonth, int endMonth,
               int startYearJoinMonth, int endYearJoinMonth, Collection<String> 
availableTargetNames) {
   
           return endYear - startYear == 1 ? twoYears(startYear, endYear, 
startMonth, endMonth, startYearJoinMonth,
                   endYearJoinMonth, availableTargetNames)
                   : moreThanTwoYears(startYear, endYear, startMonth, endMonth, 
availableTargetNames);
       }
   
   
    
       private List<String> twoYears(int startYear, int endYear, int 
startMonth, int endMonth,
               int startYearJoinMonth, int endYearJoinMonth, Collection<String> 
availableTargetNames
       ) {
           List<String> result = new ArrayList<>();
           int endCondition;
           endCondition = Integer.parseInt(startYear + "12");
           for (int i = startYearJoinMonth; i <= endCondition; i++) {
               for (String availableTargetName : availableTargetNames) {
                   if (availableTargetName.endsWith(String.valueOf(i))) {
                       result.add(availableTargetName);
                   }
               }
           }
   
           endCondition = Integer.parseInt(endYear + "01");
           for (int i = endYearJoinMonth; i >= endCondition; i--) {
               for (String availableTargetName : availableTargetNames) {
                   if (availableTargetName.endsWith(String.valueOf(i))) {
                       result.add(availableTargetName);
                   }
               }
           }
           return result;
       }
   
       private List<String> moreThanTwoYears(int startYear, int endYear, int 
startMonth, int endMonth,
               Collection<String> availableTargetNames) {
           throw new UnsupportedOperationException("Unsupported more than two 
years.");
       }
   
   
   }
   
   ```
   
   ##### The database fragmentation algorithm is configured as follows:
   
   ```java
   import com.google.common.collect.Range;
   import java.util.ArrayList;
   import java.util.Collection;
   import java.util.Date;
   import java.util.List;
   import 
org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
   import 
org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
   import 
org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
   
   
   public class DatabaseShardingAlgorithm implements 
StandardShardingAlgorithm<Date> {
   
       public static final String DATABASE_SHARDING_ALGORITHM = 
"databaseShardingAlgorithm";
   
      
       @Override
       public String doSharding(Collection<String> availableTargetNames, 
PreciseShardingValue<Date> shardingValue) {
           Long value = shardingValue.getValue().getTime();
           if (value <= 0) {
               throw new UnsupportedOperationException("preciseShardingValue is 
null");
           }
           for (String availableTargetName : availableTargetNames) {
               return availableTargetName;
           }
           return null;
       }
   
       @Override
       public Collection<String> doSharding(Collection<String> 
availableTargetNames, RangeShardingValue<Date> rangeShardingValue) {
   
           List<String> result = new ArrayList<>();
           Range<Date> range = rangeShardingValue.getValueRange();
           long startMillisecond = range.lowerEndpoint().getTime();
           // 起始年和结束年
           int startYear = 
Integer.parseInt(DateUtil.getYearByMillisecond(startMillisecond));
           return theSameYear(String.valueOf(startYear), availableTargetNames, 
result);
       }
   
       // 同一年,说明只需要一个库
       private Collection<String> theSameYear(String startTime, 
Collection<String> availableTargetNames, List<String> result) {
   
           for (String availableTargetName : availableTargetNames) {
               result.add(availableTargetName);
               break;
           }
           return result;
       }
   
   
       private Collection<String> differentYear(int startYear, int endYear, 
Collection<String> availableTargetNames, List<String> result) {
           for (String availableTargetName : availableTargetNames) {
               for (int i = startYear; i <= endYear; i++) {
                   if (availableTargetName.endsWith(String.valueOf(i))) 
result.add(availableTargetName);
               }
           }
           return result;
       }
   
       @Override
       public void init() {
   
       }
   
       @Override
       public String getType() {
           return DATABASE_SHARDING_ALGORITHM;
       }
   }
   
   ```
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to