springboot整合shardingjdbc实现简单水平分表

springboot整合shardingjdbc

1.引入依赖

这里是整合mybatis,都一样,shardingjdbc通过自定义的数据源来拦住你的sql语句进行改写
一定要注意druid数据源,不能使用自动装配的,要通过shardingjdbc去实例化数据源,那个自动装配会spring去实例化,用了自动装配也可以通过启动类注解排除

@SpringBootApplication(scanBasePackages="com.xxx",exclude={DruidDataSourceAutoConfigure.class})

pom.xml

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

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.20</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.6</version>
        </dependency>

2.编写配置文件

两个配置文件 一样的 二选一

application.properties


spring.shardingsphere.datasource.names=ds0

spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.url=jdbc:mysql://127.0.0.1:3308/test_user?characterEncoding=utf8&serverTimezone=UTC&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root


spring.shardingsphere.sharding.tables.test_user.actual-data-nodes=ds0.test_user_$->{1..2}
spring.shardingsphere.sharding.tables.test_user.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.test_user.table-strategy.standard.precise-algorithm-class-name=com.jsu.lzj.config.MyTablePreciseShardingAlgorithm
spring.shardingsphere.sharding.tables.test_user.table-strategy.standard.range-algorithm-class-name=com.jsu.lzj.config.MyTableRangeShardingAlgorithm
spring.shardingsphere.sharding.tables.test_user.key-generator.column=id
spring.shardingsphere.sharding.tables.test_user.key-generator.type=SNOWFLAKE

spring.shardingsphere.props.sql.show = true

mybatis.type-aliases-package=com/jsu/lzj/entity
mybatis.mapper-locations=classpath:mapper/*.xml

application.yml

server:
  port: 8080

spring:
  #  datasource:
  #    url: jdbc:mysql://localhost:3308/test_user?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
  #    driver-class-name: com.mysql.cj.jdbc.Driver
  #    username: root
  #    password: root

  shardingsphere:
    defaultDataSourceName: ds0
    #配置数据源 可以配置多个 实现分库
    datasource:
      names: ds0
      ds0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3308/test_user?characterEncoding=utf8&serverTimezone=UTC&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false
        username: root
        password: root
    sharding:
      tables:
        # 配置逻辑表和真实表 test_user 逻辑表  ds0上面的数据源 test_user_1 和 test_user_2真实表
        test_user:
          actual-data-nodes: ds0.test_user_$->{1..2}
          #主键生成策略
          key-generator.column: id
          #雪花算法
          key-generator.type: SNOWFLAKE

          #配置分片策略
          table-strategy:
            standard:
              sharding-column: id
              precise-algorithm-class-name: com.jsu.lzj.config.MyTablePreciseShardingAlgorithm
              range-algorithm-class-name: com.jsu.lzj.config.MyTableRangeShardingAlgorithm

#            inline:
#              # 最简洁的分片方式  分片建
#              sharding=column: id
#              # 分片策略 id是integer的  id%2 + 1
#              algorithm-expression: test_user_${id % 2 + 1}
# 打印sql语句
    props:
      sql:
        show: true

3.自定义分片算法 (可以直接用上面的行表达式分片)

自定义精准分片算法

package com.jsu.lzj.config;

import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;

import java.util.Collection;

/**
 * 精准分片策略 作用于 = in 等操作
 * @author lzj
 * @date 2022/3/24
 */
public class MyTablePreciseShardingAlgorithm implements PreciseShardingAlgorithm<Integer> {
    
    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<Integer> preciseShardingValue) {
        //获得分片建的id
        Integer value = preciseShardingValue.getValue();
        //根据分片键去取余+1分表
        return "test_user_" + (value % 2 + 1) ;
    }
}

自定义范围分片策略

package com.jsu.lzj.config;

import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.util.ArrayList;
import java.util.Collection;

/**
 * 范围分片算法策略 作用于between  > <  >= <=
 * @author lzj
 * @date 2022/3/24
 */
public class MyTableRangeShardingAlgorithm implements RangeShardingAlgorithm<Integer> {
    @Override
    public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Integer> rangeShardingValue) {
        Collection<String> result = new ArrayList<String>();
        int start = 1;
        int end = collection.size();

        //获取最大值和最小值 没有就会抛出异常 我们捕获他就好
        try{
            start = rangeShardingValue.getValueRange().lowerEndpoint();
        }catch(IllegalStateException e){
            System.out.println("java.lang.IllegalStateException: range unbounded on this side");
        }

        try{
            end = rangeShardingValue.getValueRange().upperEndpoint();
        }catch(IllegalStateException e){
            System.out.println("java.lang.IllegalStateException: range unbounded on this side");
        }

        
        for(int i=start; i <= end; i++){
            //根据范围判断需要查询哪些表
            //collection中包含所有真实表名 我们配置文件中的 ${1..2}  说明有两张
            String tableName =  "test_user_"+ ( i % 2 + 1);
            if(collection.contains(tableName)){
                if(result.contains(tableName)){
                    result.add(tableName);
                }
            }
        }

        return result;
    }
}

4.总结

接下来我们就可以和平常一样写sql去查就行,当我们查询逻辑表的时候,shardingjdbc就会帮我们拦截,根据分片键决定选择哪一张实际表

如果查询条件不包含分片键就会路由到所有表进行查询,最后合并结果

当我们插入不含分片键,也没有在shardingjdbc中配置自动生成策略应该会报错

注意事项

注意那个数据源的地方

注意springboottest

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MySpringBootApplication.class)
分库分表有四种
水平分表:将同样的表格分成多个
垂直分表:将一个表格的不同属性分到多个表格里
水平分库:将同样的表格分成多个到不同数据库
垂直分库:将不同的表格分到不同的数据库,专库专用
shardingjdbc执行流程
sql解析:首先拦截你的sql,然后经过词法分析决定哪些字段需要改写
sql路由:根据分片键决定要路由到哪一些表中
sql改写:将sql逻辑表和其他需要改写的sql字段改写成真实的sql
sql执行:执行sql语句
结果合并:将返回的结果进行合并处理
参考资料:

shardingjdbc官网

分片策略文章解析

参考入门博客

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Sharding-JDBC 是一款基于 JDBC 的数据库中间件,用于将一个大型数据库表拆分成多个小表存储在不同的数据库中。Spring Boot 是一个非常流行的 Java 开发框架,它提供了很多方便的功能,比如自动配置、自动装配等,使得开发过程变得更加简单。 要在 Spring Boot整合 Sharding-JDBC,需要完成以下几个步骤: 1. 引入 Sharding-JDBC 的依赖 在 pom.xml 文件中添加 Sharding-JDBC 和对应的数据库驱动的依赖: ``` <dependency> <groupId>io.shardingjdbc</groupId> <artifactId>sharding-jdbc-core</artifactId> <version>${sharding-jdbc.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> ``` 2. 配置 Sharding-JDBC 的数据源 在 application.yml(或 application.properties)文件中配置 Sharding-JDBC 的数据源。这里以 MySQL 数据库为例: ``` spring: datasource: driver-class-name: com.mysql.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource username: root password: 123456 url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false shardingsphere: datasource: names: ds0, ds1 ds0: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/test0?useUnicode=true&characterEncoding=utf8&useSSL=false username: root password: 123456 ds1: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf8&useSSL=false username: root password: 123456 sharding: tables: user_info: actualDataNodes: ds$->{0..1}.user_info$->{0..1} tableStrategy: standard: shardingColumn: id preciseAlgorithmClassName: io.shardingjdbc.core.api.algorithm.sharding.PreciseModuloShardingAlgorithm rangeAlgorithmClassName: io.shardingjdbc.core.api.algorithm.sharding.RangeModuloShardingAlgorithm ``` 其中,`datasource.names` 配置了数据源的名称,`datasource.ds0` 和 `datasource.ds1` 分别配置了两个数据库实例的连接信息。`sharding.tables` 配置了需要进行分片的表的信息,`actualDataNodes` 配置了分片后的数据节点,`tableStrategy` 配置了分片算法。 3. 配置 MyBatis 如果使用 MyBatis 作为 ORM 框架,需要在 MyBatis 的配置文件中配置 Sharding-JDBC 的插件和数据源: ``` <plugins> <plugin interceptor="io.shardingjdbc.spring.boot.masterslave.SpringBootMasterSlavePlugin"/> </plugins> <environments default="master_slave"> <environment id="master_slave"> <transactionManager type="JDBC"/> <dataSource type="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${spring.datasource.driver-class-name}"/> <property name="url" value="${spring.datasource.url}"/> <property name="username" value="${spring.datasource.username}"/> <property name="password" value="${spring.datasource.password}"/> </dataSource> </environment> </environments> ``` 4. 测试分片效果 完成以上步骤后,就可以启动应用程序并测试分片效果了。可以插入一些数据并进行查询,观察数据是否被正确地分配到了不同的数据库中。 以上是整合 Sharding-JDBCSpring Boot 的基本步骤。当然,在实际应用中还需要根据具体业务需求进行更加详细的配置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值