环境准备

在商业开发当中,有一些需求会将几年的数据放到一个库里面,但是当前库里面会建很多表,表明是按照年份和月份来建。我们这里为了演示技术,将会按照一个年份建一个库,一个年份对应的库里面按照日期建立365个表。 我这里建立了两个库 【ShardingSphere】springboot整合shardingjdbc按照年月分库分表-LMLPHP

每个库对应的表结构如下:

CREATE TABLE `test_20210601` (
  `id` bigint(32) NOT NULL,
  `year_value` char(4) DEFAULT NULL COMMENT '年份值',
  `day_value` char(8) DEFAULT NULL COMMENT '日期值',
  `content` varchar(255) DEFAULT NULL COMMENT '内容',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
...
CREATE TABLE `test_20210610` (
  `id` bigint(32) NOT NULL,
  `year_value` char(4) DEFAULT NULL COMMENT '年份值',
  `day_value` char(8) DEFAULT NULL COMMENT '日期值',
  `content` varchar(255) DEFAULT NULL COMMENT '内容',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

配置分库分表策略

server.port=10080

spring.shardingsphere.datasource.names=ds2021,ds2022

# 配置第一个数据库
spring.shardingsphere.datasource.ds2021.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds2021.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds2021.jdbc-url=jdbc:mysql://localhost:3306/ds2021
spring.shardingsphere.datasource.ds2021.username=root
spring.shardingsphere.datasource.ds2021.password=root

# 配置第二个数据库
spring.shardingsphere.datasource.ds2022.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds2022.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds2022.jdbc-url=jdbc:mysql://localhost:3306/ds2022
spring.shardingsphere.datasource.ds2022.username=root
spring.shardingsphere.datasource.ds2022.password=root

# 配置test表的分库策略
spring.shardingsphere.sharding.tables.test.database-strategy.inline.sharding-column=year_value
spring.shardingsphere.sharding.tables.test.database-strategy.inline.algorithm-expression=ds$->{year_value}

# 配置trans_channel的分表策略
spring.shardingsphere.sharding.tables.test.actual-data-nodes=ds$->{2021..2022}.test_$->{20210601..20210610}
spring.shardingsphere.sharding.tables.test.table-strategy.inline.sharding-column=day_value
spring.shardingsphere.sharding.tables.test.table-strategy.inline.algorithm-expression=test_$->{day_value}

# 添加trans_channel表的id生成策略
spring.shardingsphere.sharding.tables.test.key-generator.column=id
spring.shardingsphere.sharding.tables.test.key-generator.type=SNOWFLAKE

测试

按照之前的套路,我们生成点代码,然后测试一下。这里不再赘述引入shardingjdbc和整合mybatis,如果不太清楚的,可以查看前面两篇文章

@RestController
@RequestMapping(value = "/test")
public class Test {

    @Autowired
    private TestService testService;

    @GetMapping(value = "/save")
    public String save() {
        testService.save();
        return "success";
    }

}

public interface TestService {

    void save();

}

public class TestServiceImpl implements TestService {

    @Autowired
    private TestDao testDao;

    @Override
    public void save() {
        Test test = new Test();
        test.setDayValue("20210602");
        test.setYearValue("2021");
        testDao.save(test);
    }

}

public interface TestDao {

    int save(Test test);

}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.echo.shardingjdbc.dao.TestDao">
    <resultMap id="BaseResultMap" type="com.echo.shardingjdbc.po.Test">
        <id column="id" jdbcType="BIGINT" property="id"/>
        <result column="year_value" jdbcType="CHAR" property="yearValue"/>
        <result column="day_value" jdbcType="CHAR" property="dayValue"/>
        <result column="content" jdbcType="VARCHAR" property="content"/>
    </resultMap>
    <sql id="Base_Column_List">
    id, year_value, day_value, content
  </sql>

    <insert id="save" parameterType="com.echo.shardingjdbc.po.Test">
    insert into test (year_value, day_value, content)
    values (#{yearValue,jdbcType=CHAR}, #{dayValue,jdbcType=CHAR}, #{content,jdbcType=VARCHAR})
  </insert>
</mapper>

调用接口http://localhost:10080/test/save,我们能够看到最终数据进入了ds2021库20210602表 【ShardingSphere】springboot整合shardingjdbc按照年月分库分表-LMLPHP

我们可以根据我们在配置的时候,定义的规则来更改我们的save值,这样就能够有效的将数据存入不同的库,不同的表。

总结

  • 按照年月日分库分表,关键就在于我们配置的时候要用到以某个字段直接作为某个库或者表的值,如:test_$->{day_value},这代表的就是日期值就是我们表的后缀
  • actual-data-nodes描述的是一个真实的取值范围,如果没有就会报错
06-13 08:49