Sharding-jdcb 数据分片配置

1.配置数据库连接池参数
在这里插入图片描述

sharding.jdbc.datasource.names=shardingdruiddatasource
sharding.jdbc.datasource.shardingdruiddatasource.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.shardingdruiddatasource.driver-class-name=com.mysql.cj.jdbc.Driver
sharding.jdbc.datasource.shardingdruiddatasource.url=jdbc:mysql://120.
sharding.jdbc.datasource.shardingdruiddatasource.username=root
sharding.jdbc.datasource.shardingdruiddatasource.password=root

default.jdbc.datasource.driver-class-name=com.mysql.jdbc.Driver
druid.initialSize=10
druid.maxActive=120
druid.minIdle=10
druid.maxWait=10000
druid.validationQuery=SELECT 1 from dual
druid.testWhileIdle=true
druid.testOnBorrow=false
druid.testOnReturn=false
druid.timeBetweenEvictionRunsMillis=60000
druid.minEvictableIdleTimeMillis=14400000
druid.maxEvictableIdleTimeMillis=28800000
druid.removeAbandoned=true
druid.removeAbandonedTimeout=1800
druid.logAbandoned=true
druid.filters=stat

2.导入依赖


```java
<properties>

    <shardingsphere.version>3.0.0.M4</shardingsphere.version>
    <druid.version>1.1.12</druid.version>
</properties>


<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>${druid.version}</version>
</dependency>


<dependency>
    <groupId>io.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>${shardingsphere.version}</version>
</dependency>

3.配置数据库表路由

```java
public class ShardingTableConfig {

   private final static Integer SHARDING_USER_TABLE_TOTAL = 3;


   public static TableRuleConfiguration getUserTableRuleConfiguration() {
      TableRuleConfiguration tableConfig = new TableRuleConfiguration();
      StandardShardingStrategyConfiguration shardingStrategyConfig = new StandardShardingStrategyConfiguration(
            "openid", new ShardingAlgorithm());
      tableConfig.setLogicTable("t_mobile_user");
      tableConfig.setActualDataNodes(
            String.format("shardingdruiddatasource.t_mobile_user${0..%d}", SHARDING_USER_TABLE_TOTAL - 1));
      tableConfig.setTableShardingStrategyConfig(shardingStrategyConfig);
      tableConfig.setKeyGeneratorColumnName("id");
      return tableConfig;
   }
   
}

4.配置数据分片算法

public class ShardingAlgorithm implements PreciseShardingAlgorithm<String> {

    /**
     * Sharding.
     *
     * @param availableTargetNames available data sources or tables's names
     * @param shardingValue        sharding value
     * @return sharding result for data source or table's name
     */
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
        long hashCode = HashUtils.fnvHash(shardingValue.getValue().toString());
        int index =(int)Math.abs(hashCode % availableTargetNames.size());
        ArrayList<String> candidateCollect = new ArrayList<>(availableTargetNames);
        String item = candidateCollect.get(index);
        log.info("shardingValue = {} 被哈希到的表为:{}", shardingValue, item);
        return item;
    }


}
public class HashUtils {


    public static long hash(String key) {
        // TODO 实现哈希算法
        return "".hashCode();
    }


    public static long fnvHash(String data) {
        int p = 16777619;
        long hash = 2166136261L;
        for (int i = 0; i < data.length(); i++) {
            hash = (hash ^ data.charAt(i)) * p;
        }
        hash += hash << 13;
        hash ^= hash >> 7;
        hash += hash << 3;
        hash ^= hash >> 17;
        hash += hash << 5;
        return hash;
    }


    public static String md5Encode(String msg) throws Exception {

        byte[] msgBytes = msg.getBytes("utf-8");
        // 声明使用Md5算法,获得 MessageDigest 对象
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        // 使用指定的字节更新摘要
        md5.update(msgBytes);
        // 完成哈希计算,获得密文
        byte[] digest = md5.digest();
        return byteArray2HexString(digest);
    }

    /**
     * 将byte数组转化为16进制字符串形式
     *
     * @param bytes 比特数组
     * @return 16进制格式字符串
     */
    private static String byteArray2HexString(byte[] bytes) {
        StringBuffer buffer = new StringBuffer(bytes.length * 2);
        int val;
        for (int i = 0; i < bytes.length; i++) {
            //将byte转化为int  如果byte是一个负数就必须要和16进制的0xff做一次与运算
            val = ((int) bytes[i]) & 0xff;
            if (val < 16) {
                buffer.append("0");
            }
            buffer.append(Integer.toHexString(val));
        }
        return buffer.toString();
    }


}

5.添加配置类

/**
 * 需要分表的数据源
 *
 * @author Hurrican
 * @Date 2019/1/28 10:59
 * @since 1.0.0
 */
@Configuration
@MapperScan(basePackages = "com.huaer.welfare.mapper", sqlSessionFactoryRef = "shardingSqlSessionFactory")
@PropertySource("classpath:jdbc.properties")
public class ShardingDatasourceConfig {

   private static final String MAPPER_LOCATION = "classpath:sqlmap/**/*.xml";

   private static final String CONFIG_LOCATION = "classpath:dataMapperConfig.xml";


   @Value("${sharding.jdbc.datasource.shardingdruiddatasource.url}")
   private String url;

   @Value("${sharding.jdbc.datasource.shardingdruiddatasource.username}")
   private String user;

   @Value("${sharding.jdbc.datasource.shardingdruiddatasource.password}")
   private String password;

   @Value("${sharding.jdbc.datasource.shardingdruiddatasource.driver-class-name}")
   private String driverClass;



   @Bean(name = "shardingDataSource")
   public DataSource getShardingDruidDataSource(@Qualifier("commonDruidProp") DruidProp druidProp )
         throws SQLException {
      DruidDataSource dataSource = new DruidDataSource();
      dataSource.setDriverClassName(driverClass);
      dataSource.setUrl(url);
      dataSource.setUsername(user);
      dataSource.setPassword(password);
      dataSource.setMaxActive(druidProp.getMaxActive());
      dataSource.setMinIdle(druidProp.getMinIdle());
      dataSource.setMaxWait(druidProp.getMaxWait());
      dataSource.setInitialSize(druidProp.getInitialSize());
      dataSource.setTestWhileIdle(druidProp.getTestWhileIdle());
      dataSource.setTestOnBorrow(druidProp.getTestOnBorrow());
      dataSource.setTestOnReturn(druidProp.getTestOnReturn());
      dataSource.setRemoveAbandoned(druidProp.getRemoveAbandoned());
      dataSource.setRemoveAbandonedTimeout(druidProp.getRemoveAbandonedTimeout());
      dataSource.setTimeBetweenEvictionRunsMillis(druidProp.getTimeBetweenEvictionRunsMillis());
      dataSource.setMinEvictableIdleTimeMillis(druidProp.getMinEvictableIdleTimeMillis());
      dataSource.setMaxEvictableIdleTimeMillis(druidProp.getMaxEvictableIdleTimeMillis());
      dataSource.setLogAbandoned(druidProp.getLogAbandoned());
      dataSource.setValidationQuery(druidProp.getValidationQuery());
      dataSource.setConnectionErrorRetryAttempts(druidProp.getConnectionErrorRetryAttempts());

      HashMap<String, DataSource> dataSourceMap = new HashMap<>(4);
      dataSourceMap.put("shardingdruiddatasource", dataSource);

      ArrayList<TableRuleConfiguration> tableRuleConfigs = new ArrayList<>(4);
      tableRuleConfigs.add(ShardingTableConfig.getUserTableRuleConfiguration());

      ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
      shardingRuleConfig.setTableRuleConfigs(tableRuleConfigs);

      // ConfigMap用于配置读写分离
      HashMap<String, Object> configMap = new HashMap<>(4);

      // sql.show 用于调试输出分表的真实SQL语句
      Properties props = new Properties();
//    props.setProperty("sql.show", "true");
      props.setProperty(ShardingPropertiesConstant.MAX_CONNECTIONS_SIZE_PER_QUERY.getKey(), "21");
      props.setProperty(ShardingPropertiesConstant.EXECUTOR_SIZE.getKey(), "20");
      return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, configMap, props);
   }

   @Bean(name = "shardingSqlSessionFactory")
   public SqlSessionFactory shardingSqlSessionFactory(@Qualifier("shardingDataSource") DataSource shardingDataSource)
         throws Exception {
      org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
      SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
      configuration.setMapUnderscoreToCamelCase(true);
      sessionFactory.setConfiguration(configuration);
      sessionFactory.setDataSource(shardingDataSource);
      sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
//    sessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver().getResource(CONFIG_LOCATION));
      return sessionFactory.getObject();
   }

   // 创建该数据源的事务管理
   @Bean(name = "primaryTransactionManager")
   public DataSourceTransactionManager primaryTransactionManager(
         @Qualifier("shardingDataSource") DataSource shardingDataSource) throws SQLException {
      return new DataSourceTransactionManager(shardingDataSource);
   }

   @Bean(name = "shardingSqlSessionTemplate")
   public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory shardingSqlSessionFactory) {
      return new SqlSessionTemplate(shardingSqlSessionFactory);
   }

源码阅读:
1.根据hash算法获取最终访问的表
|
2.将原来sql中的表名替换成由hash算法获取到的表名
|
|

|

3.调用mybatis excute方法执行sql语句
|
调用query方法查询
|

获取查询结果
|

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值