zoukankan      html  css  js  c++  java
  • sharding-jdbc多数据源配置分库分表

    由于sharding-jdbc对sql有多种语法限制,如果用同一个数据源,不分表的sql语句也无法规避限制

    因此可以使用多数据源方式解决该问题。

    1指定mapper注解java接口所在的目录

    basePackages = "com.order.mapper.second"

    2指定mapper sql语句xml所在的目录

    String MAPPER_LOCATION = "classpath:mapper/second/*.xml"
    
    
    package com.order.config;
    
    import com.order.dao.RangeShardingTableStrategy;
    import com.order.dao.ShardingTableStrategy;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.shardingsphere.api.config.sharding.KeyGeneratorConfiguration;
    import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
    import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
    import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
    import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
    import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
    import org.apache.shardingsphere.spring.boot.util.DataSourceUtil;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    
    import javax.sql.DataSource;
    import java.sql.SQLException;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Properties;
    
    @Configuration
    @MapperScan(basePackages = "com.order.mapper.second", sqlSessionFactoryRef = "secondSqlSessionFactory")
    public class SecondDataSourceConfig {
    
        // 精确到目录,以便跟其他数据源隔离
        static final String MAPPER_LOCATION = "classpath:mapper/second/*.xml";
        @Value("${spring.shardingsphere.datasource.order.jdbc-url}")
        private String url;
        @Value("${spring.shardingsphere.datasource.order.username}")
        private String username;
        @Value("${spring.shardingsphere.datasource.order.password}")
        private String password;
    
        /**
         * 创建sharding-jdbc的DataSource实例
         *
         * @return
         */
        @Bean(name = "secondDataSource")
        @Qualifier("secondDataSource")
        public DataSource shardingDataSource() {
            //return DataSourceBuilder.create().build();
            return getShardingDataSource();
        }
    
        @Bean(name = "secondSqlSessionFactory")
        public SqlSessionFactory clusterSqlSessionFactory(@Qualifier("secondDataSource") DataSource clusterDataSource)
                throws Exception {
            final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(clusterDataSource);
            sessionFactory.setMapperLocations(
                    new PathMatchingResourcePatternResolver().getResources(SecondDataSourceConfig.MAPPER_LOCATION));
            return sessionFactory.getObject();
        }
    
    
        DataSource getShardingDataSource() {
            ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
            shardingRuleConfig.getTableRuleConfigs().add(getOrderTableRuleConfiguration());
            shardingRuleConfig.getBindingTableGroups().add("order_all");
            //shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("order_id", new ShardingTableStrategy()));
            shardingRuleConfig.setDefaultTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("order_id", new ShardingTableStrategy(),new RangeShardingTableStrategy()));
            try {
                return ShardingDataSourceFactory.createDataSource(createDataSourceMap(), shardingRuleConfig, new Properties());
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        private static KeyGeneratorConfiguration getKeyGeneratorConfiguration() {
            KeyGeneratorConfiguration result = new KeyGeneratorConfiguration("SNOWFLAKE", "order_id");
            return result;
        }
    
        TableRuleConfiguration getOrderTableRuleConfiguration() {
            TableRuleConfiguration result = new TableRuleConfiguration("order_all", "order.order_all_${0..15}");
            //result.setKeyGeneratorConfig(getKeyGeneratorConfiguration());
            return result;
        }
    
        @ConfigurationProperties(prefix = "spring.shardingsphere.datasource.order")
        Map<String, DataSource> createDataSourceMap() {
            Map<String, DataSource> result = new HashMap<>();
            // 配置真实数据源
            Map<String, Object> dataSourceProperties = new HashMap<>();
            dataSourceProperties.put("DriverClassName", "com.mysql.jdbc.Driver");
            dataSourceProperties.put("jdbcUrl", url);
            dataSourceProperties.put("username", username);
            dataSourceProperties.put("password", password);
            try {
                DataSource ds = DataSourceUtil.getDataSource("com.zaxxer.hikari.HikariDataSource", dataSourceProperties);
                result.put("order", ds);
            } catch (ReflectiveOperationException e) {
                e.printStackTrace();
            }
            return result;
        }
    }

     为了便于查询,需要设置分表策略,范围查询策略

            shardingRuleConfig.setDefaultTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("order_id", new ShardingTableStrategy(),new RangeShardingTableStrategy()))

    这里面2个自定义类如下

    ShardingTableStrategy
    public class ShardingTableStrategy implements PreciseShardingAlgorithm<String> {
    
        @Override
        public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
    
            for (String tableName : collection) {
                long divide = Math.abs(preciseShardingValue.getValue().hashCode()) % 16;
                if (tableName.endsWith("" + divide)) {
                    return tableName;
                }
            }
            throw new IllegalArgumentException();
        }
    }
    RangeShardingTableStrategy
    public class RangeShardingTableStrategy implements RangeShardingAlgorithm<String> {
    
    
        @Override
        public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<String> rangeShardingValue) {
            Collection<String> collect = new ArrayList<>();
            for (int i = 0; i < 16; i++) {
                for (String each : collection) {
                    if (each.endsWith(i % collection.size() + "")) {
                        collect.add(each);
                    }
                }
            }
            return collect;
        }
    }
  • 相关阅读:
    2008年具有高校自主选拔录取资格的考生名单 江苏版
    OpenGL ES 2.0 for iPhone Tutorial
    Mathematica三维点插值算法(高维插值,多维插值)
    Mathematica颜色系,你喜欢哪一个?
    Khronos EGL and Apple EAGL
    ssh 免密码登陆配置
    2008年高考招生:北京大学自主选拔录取资格考生名单
    PlotLegends 应用
    Mathematica 如何更改文档的样式
    您为何而工作?
  • 原文地址:https://www.cnblogs.com/lixiaoran/p/12991670.html
Copyright © 2011-2022 走看看