雁过留声 发表于 2023-5-24 11:52:30

springboot~对应sharding-jdbc实现分库分表

原因

当mysql数据库单表大于1千万以后,查询的性能就不能保证了,我们必须考虑分库,分表的方案了,还好,sharding-jdbc可以很优雅的与springboot对接,完成对mysql的分库和分表。
依赖整理

为了不影响其它小容量的表,所有添加了动态数据源,只对需要分库分表的进行配置即可

[*]com.baomidou:dynamic-datasource-spring-boot-starter:3.3.1
[*]org.apache.shardingsphere:sharding-jdbc-spring-boot-starter:4.1.1
[*]com.baomidou:dynamic-datasource-spring-boot-starter:3.3.1
[*]com.baomidou:mybatis-plus-boot-starter:3.4.1
    <dependency>
      <groupId>org.apache.shardingsphere</groupId>
      <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>配置整理

spring:
application.name: sharding-jdbc
datasource:
    dynamic:
      primary: master0
      datasource:
      master0:
          url: jdbc:mysql://192.168.4.xx:3306/sharding0?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
          username: root
          password: xxx
          driver-class-name: com.mysql.jdbc.Driver
      master1:
          url: jdbc:mysql://192.168.4.xx:3306/sharding1?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
          username: root
          password: xxx
          driver-class-name: com.mysql.jdbc.Driver

shardingsphere:
    datasource:
      names: ds0,ds1
      ds0:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql://192.168.4.xx:3306/sharding0?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
      username: root
      password: xxx
      type: com.zaxxer.hikari.HikariDataSource
      ds1:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql://192.168.4.xx:3306/sharding1?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
      username: root
      password: xxx
      type: com.zaxxer.hikari.HikariDataSource #必须个type,否则报错
    sharding:
      tables:
      t_order:
          #key-generator:
          #column: id
          #type: SNOWFLAKE
          actual-data-nodes: ds$->{0..1}.t_order_$->{0..1} #需要开发人员手动按规则建立数据表
          database-strategy:
            inline:
            sharding-column: id
            algorithm‐expression: ds$->{id % 2}
          table-strategy:
            inline:
            sharding-column: id
            algorithm‐expression: t_order_$->{id % 2}
    props:
      sql:
      show: true   # 日志显示SQL

mybatis:
mapperLocations: classpath:mapper/*.xml
typeAliasesPackage: com.lind.shardingjdbc.entity
configuration:
    mapUnderscoreToCamelCase: true提前建立表分库和分表

https://img2023.cnblogs.com/blog/118538/202305/118538-20230524110958523-921036723.png
测试代码整理


[*]配置类
@Configuration
@AutoConfigureBefore({ DynamicDataSourceAutoConfiguration.class, SpringBootConfiguration.class })
public class DataSourceConfiguration {

        // 分表数据源名称
        private static final String SHARDING_DATA_SOURCE_NAME = "sharding";
        /**
       * shardingjdbc有四种数据源,需要根据业务注入不同的数据源
       *
       * <p>
       * 1. 未使用分片, 脱敏的名称(默认): shardingDataSource;
       * <p>
       * 2. 主从数据源: masterSlaveDataSource;
       * <p>
       * 3. 脱敏数据源:encryptDataSource;
       * <p>
       * 4. 影子数据源:shadowDataSource
       */
        @Lazy
        @Resource(name = "shardingDataSource")
        AbstractDataSourceAdapter shardingDataSource;
        // 动态数据源配置项
        @Autowired
        private DynamicDataSourceProperties properties;

        @Bean
        public DynamicDataSourceProvider dynamicDataSourceProvider() {
                Map<String, DataSourceProperty> datasourceMap = properties.getDatasource();
                return new AbstractDataSourceProvider() {
                        @Override
                        public Map<String, DataSource> loadDataSources() {
                                Map<String, DataSource> dataSourceMap = createDataSourceMap(datasourceMap);
                                // 将 shardingjdbc 管理的数据源也交给动态数据源管理
                                dataSourceMap.put(SHARDING_DATA_SOURCE_NAME, shardingDataSource);
                                return dataSourceMap;
                        }
                };
        }

        /**
       * 将动态数据源设置为首选的 当spring存在多个数据源时, 自动注入的是首选的对象 设置为主要的数据源之后,就可以支持shardingjdbc原生的配置方式了
       */
        @Primary
        @Bean
        public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {
                DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
                dataSource.setPrimary(properties.getPrimary());
                dataSource.setStrict(properties.getStrict());
                dataSource.setStrategy(properties.getStrategy());
                dataSource.setProvider(dynamicDataSourceProvider);
                dataSource.setP6spy(properties.getP6spy());
                dataSource.setSeata(properties.getSeata());
                return dataSource;
        }

}

[*]实体类和mapper类
@Data
@TableName("t_order")
public class Order {

        @TableId(type = IdType.ASSIGN_ID)
        Long orderId;

        double amount;

        Integer userId;

}
@Mapper
public interface OrderMapper extends BaseMapper<Order> {

}

[*]分表的测试
    @GetMapping("insert")
        @DS("sharding")
        public ResponseEntity test() {
                Order order = new Order();
                order.setAmount(100);
                order.setUserId(1);
                orderMapper.insert(order);
                return ResponseEntity.ok("success");
        }

[*]不进行分表的测试
    @GetMapping("insert-not-sharding")
        public ResponseEntity testNotSharding() {
                Order order = new Order();
                order.setAmount(101);
                order.setUserId(2);
                orderMapper.insert(order);
                return ResponseEntity.ok("success");
        }
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: springboot~对应sharding-jdbc实现分库分表