springboot sharding-jdbc分表

sharding-jdbc分表

    • pom文件导包
    • yml配置
    • sharding数据库配置
    • 分片策略

文章例子为按月份分表,将表按月份分为(表_1,表_2…表_12)
ShardingSphere

pom文件导包

    <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
      <version>5.8.5</version>
    </dependency>
   
    <dependency>
		<groupId>org.apache.shardingsphere</groupId>
		<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
		<version>4.1.1</version>
	</dependency>

yml配置

spring:
  shardingsphere:
    datasource: # 数据源
      master:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.jdbc.Driver
        username: ## 用户名称
        password: ## 密码
        jdbcUrl: jdbc:mysql://ip:host/数据库名?useUnicode=true&amp;autoReconnect=true&amp;characterEncoding=UTF-8&useSSL=true&zeroDateTimeBehavior=convertToNull
      names: master
    props:
      sql.show: true #是否开启SQL显示,默认值: false
      max.connections.size.per.query: 8 # 每个查询可以打开的最大连接数量,默认为1,此处可加快项目启动时shardingsphere加载数据库表元数据的速度
    sharding:
      tables:
        ${表前缀}: # 如 t_a_1~t_a_12写t_a
          actual-data-nodes: master.表前缀_$->{1..12}  #表分布情况 {数据源分支.表名}
          table-strategy:
            standard: # 数据库表分片策略
              shardingColumn: insert_time ##按该字段分片
              preciseAlgorithmClassName: **.MonthPreciseShardingAlgorithm  ##对应类全路径
              rangeAlgorithmClassName: **.MonthRangeShardingAlgorithm ##对应类全路径

sharding数据库配置

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * 数据库配置
 *
 */
@Configuration
@MapperScan(basePackages = "分表dao类所在包", sqlSessionTemplateRef = "shardingSqlSessionTemplate")
public class ShardingDataSourceConfig {

    @Bean(name = "shardingSqlSessionFactory")
    public SqlSessionFactory shardingSqlSessionFactory(@Qualifier("shardingDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/sharding/*.xml"));
        return bean.getObject();
    }

    @Bean(name = "shardingTransactionManager")
    public DataSourceTransactionManager shardingTransactionManager(@Qualifier("shardingDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

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


分片策略

MonthPreciseShardingAlgorithm.java

import cn.hutool.core.date.DateUtil
import org.apache.commons.lang3.StringUtils;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;

import java.util.Collection;

/**
 * 表精确分片算法
 * in或=
 * 按时间月份分片
 * 使用String类型进行分片,则对于分片字段类型应为String
 *
 */
public class MonthPreciseShardingAlgorithm implements PreciseShardingAlgorithm<String> {
    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
        // 逻辑表名
        String logicTableName = preciseShardingValue.getLogicTableName();
        // 分片值
        String value = preciseShardingValue.getValue();
        if (StringUtils.isBlank(value)) {
            throw new BusinessException("分片值异常");
        }
        int mm = DateUtil.month(DateUtil.parse(value)) + 1;

        return logicTableName + "_" + mm;
    }
}

MonthRangeShardingAlgorithm.java

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Range;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.util.Calendar;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * 表范围分片
 * 

* 按月份分片 * */ public class MonthRangeShardingAlgorithm implements RangeShardingAlgorithm<String> { @Override public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<String> rangeShardingValue) { String logicTableName = rangeShardingValue.getLogicTableName(); Range<String> valueRange = rangeShardingValue.getValueRange(); try { String startDate = valueRange.lowerEndpoint(); String endDate = valueRange.upperEndpoint(); return getMonthTables(startDate, endDate, logicTableName); } catch (Exception e) { e.printStackTrace(); return collection; } } /** * 获取月表 * * @param startDate 起始时间 * @param endDate 结束时间 * @param logicTableName 逻辑表名 * @return 结果表名列表 */ public Set<String> getMonthTables(String startDate, String endDate, String logicTableName) { DateTime startDateTime = DateUtil.parse(startDate); DateTime endDateTime = DateUtil.parse(endDate); Calendar start = Calendar.getInstance(); Calendar end = Calendar.getInstance(); start.setTime(startDateTime); end.setTime(endDateTime); Set<String> result = new HashSet<>(); // 添加起始月和结束月 result.add(logicTableName + "_" + (start.get(Calendar.MONTH) + 1)); result.add(logicTableName + "_" + (end.get(Calendar.MONTH) + 1)); while (start.before(end)) { result.add(logicTableName + "_" + (start.get(Calendar.MONTH) + 1)); start.add(Calendar.MONTH, 1); } return result; } }

你可能感兴趣的:(java后端,spring,boot,mybatis,spring,数据库)