SpringBoot集成Sharding-JDBC-5.3.0分库分表

avatar
作者
猴君
阅读量:3

 Sharding-JDBC系列

1、Sharding-JDBC分库分表的基本使用

2、Sharding-JDBC分库分表之SpringBoot分片策略

3、Sharding-JDBC分库分表之SpringBoot主从配置

4、SpringBoot集成Sharding-JDBC-5.3.0分库分表

前言

Apache ShardingSphere,作为全球知名的基础软件开源项目,最早可追溯到 2015 年。其最初版本是当当网内部项目孵化而成,其目的是为了解决数据库水平拆分而产生的分布式问题。在 2016 年正式开源,逐渐得到了更多公司的关注和贡献,项目规模和影响力逐步扩大。在 2018 年, 该项目进入Apache 基金会孵化器,并于 2020 年成为顶级项目成功孵化。

ShardingSphere 4.x版本是在2019年发布,5.x版本是在2021年发布。在2020年成为Apache基金会顶级项目之后,特别是到5.3.0,在规范化、性能优化、分片策略等做了很多改动。

《Sharding-JDBC系列》的前3篇博文都是基于Sharding-JDBC-4.1.1,5.x 之后有许多改动,以下以ShardingSphere 5.3.0版本,分享ShardingSphere在SpringBoot中的使用。

准备工作

以下以订单分表为例,介绍Sharding-JDBC 5.3.0的基本使用。

1)订单表:订单表的字段有订单id、会员id、总价格、状态、下单时间;

2)创建两个订单表,分表为tb_order_1和tb_order_2;

3)分表规则:以订单id分表,id被2整除的放tb_order_1,不能被2整除的放tb_order_2;

本篇的示例和Sharding-JDBC分库分表的基本使用-CSDN博客是一样,只是使用的Sharding-JDBC的版本不一样,可以对比着查看。

导入依赖

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">     <parent>         <groupId>org.springframework.boot</groupId>         <artifactId>spring-boot-starter-parent</artifactId>         <version>2.7.1</version>         <relativePath/> <!-- lookup parent from repository -->     </parent>     <modelVersion>4.0.0</modelVersion>      <artifactId>Sharding-JDBC-demo2</artifactId>      <dependencies>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-web</artifactId>         </dependency>         <dependency>             <groupId>com.baomidou</groupId>             <artifactId>mybatis-plus-boot-starter</artifactId>             <version>3.4.1</version>         </dependency>         <dependency>             <groupId>org.apache.shardingsphere</groupId>             <artifactId>shardingsphere-jdbc-core</artifactId>             <version>5.3.0</version>         </dependency>         <dependency>             <groupId>org.yaml</groupId>             <artifactId>snakeyaml</artifactId>             <version>1.33</version>         </dependency>         <dependency>             <groupId>mysql</groupId>             <artifactId>mysql-connector-java</artifactId>             <version>8.0.28</version>         </dependency>         <dependency>             <groupId>org.projectlombok</groupId>             <artifactId>lombok</artifactId>             <version>1.18.22</version>             <scope>compile</scope>         </dependency>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-devtools</artifactId>             <optional>true</optional>             <scope>runtime</scope>         </dependency>     </dependencies>  </project>

Sharding-JDBC 5.3.0的依赖是shardingsphere-jdbc-core;

在5.x之前,依赖是sharding-jdbc-spring-boot-starter。5.0到5.2,依赖是shardingsphere-jdbc-core-spring-boot-starter;

如果springboot的版本为2.x,会提示org.yaml.snakeyaml.LoaderOptions找不到setCodePointLimit()方法。该类在snakeyaml.jar包,且1.33之后才有这个方法。springboot依赖的snakeyaml为1.30。解决方式如下:

1)方法1:使用springboot 3.x的版本,jdk需要升级到17。idea也要升级为2022之后的版本;

2)方法2:手动引入snakeyaml.jar的1.33版本;

yml配置

从 5.1.2 版本开始,Sharding-JDBC提供了原生JDBC驱动ShardingSphereDriver。在5.3.x之后,配置也做了规范化处理。

4.1 application.yml的配置

server:   port: 8080 spring:   main:     # 处理连接池冲突     allow-bean-definition-overriding: true   datasource:     driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver     url: jdbc:shardingsphere:classpath:sharding.yml

在spring.datasource.url中,配置shardingsphere的配置文件路径为sharding.yml

4.2 sharding.yml的配置

dataSources:   order_ds:     dataSourceClassName: com.zaxxer.hikari.HikariDataSource     driverClassName: com.mysql.cj.jdbc.Driver     url: jdbc:mysql://localhost:3306/shardingjdbctest?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false     username: root     password: 123456  rules: - !SHARDING   tables:     tb_order: #逻辑表       actualDataNodes: order_ds.tb_order_$->{1..2}  #order1:数据源名称;两个tb_order表,分别为tb_order_1和tb_order_2       keyGenerateStrategy: # 指定主键生成策略         column: order_id         keyGeneratorName: snowflake       tableStrategy:         standard:  #没有inline策略           shardingColumn: order_id   #分片键。对id进行分表           shardingAlgorithmName: order_inline   shardingAlgorithms:  #分片算法     order_inline: #算法名称       type: inline #算法类型       props:         algorithm-expression: tb_order_$->{order_id % 2 + 1}  #分片算法   keyGenerators:  # 主键生成器     snowflake:       type: SNOWFLAKE props:   sql-show: true  # 是否打印sql

1)独立分片规则的文件,与Spring分离;

2)以驼峰命名取代了下划线命名;

3)在tables规则中,只配置策略及对应算法名称;

4)分片策略中,取消了inline类型的分片策略,只作为标准分片中的inline算法类型;

5)独立分片算法、主键生成器等,当不同的table需要相同的算法时,可以复用;

详细配置查看:YAML 配置 :: ShardingSphere

 实体类

package com.jingai.sharing.jdbc.entity;  import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.ToString;  import java.util.Date;  @Data @ToString @TableName("tb_order") public class OrderEntity {      private long orderId;     private long memberId;     private float totalPrice;     private String status;     private Date orderTime;  }

在实体类中,@TableName指定配置中的逻辑表。

Mapper类

package com.jingai.sharing.jdbc.dao;  import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.jingai.sharing.jdbc.entity.OrderEntity; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Options;  public interface OrderMapper extends BaseMapper<OrderEntity> {      @Insert("insert into tb_order(member_id, total_price, status, order_time) values " +             "(#{memberId}, #{totalPrice}, #{status}, #{orderTime})")     @Options(useGeneratedKeys = true, keyProperty = "orderId")     int insert2(OrderEntity order); } 

在5.2的配置中,通过key-generator设置了逻辑表的主键生成策略为雪花算法。当进行数据插入时,需要编写新的插入接口,不能直接使用Mybatis-plus中的insert()接口。因为在默认的insert()接口中,实体对象的orderId为0,不会走配置的雪花算法。

Service类

package com.jingai.sharing.jdbc.service;  import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.jingai.sharing.jdbc.dao.OrderMapper; import com.jingai.sharing.jdbc.entity.OrderEntity; import org.springframework.stereotype.Service;  import javax.annotation.Resource;  @Service public class OrderService extends ServiceImpl<OrderMapper, OrderEntity> {      @Resource     private OrderMapper orderMapper;      public long insert2(OrderEntity order) {         int rs = orderMapper.insert2(order);         return rs > 0 ? order.getOrderId() : 0;     }  } 

为了便于测试,此处省略了Service的接口类。

Controller类

@RestController public class OrderController {      @Resource     private OrderService orderService;      @RequestMapping("order")     public String order(OrderEntity order) {         order.setOrderTime(new Date());         long insert = orderService.insert2(order);         return insert > 0 ? "success" : "fail";     }      @RequestMapping("list")     public List<OrderEntity> list() {         return orderService.list();     }  }

8.1 访问order接口

访问order接口,添加记录,打印的日志如下:

id为1018095401464496128,分片到tb_order_1。

8.2 访问list接口

访问list接口,查询全部数据,打印的日志如下:

由于list是查询全部,所以会进行全局扫描查询,需要查询tb_order_1和tb_order_2两个表。此处通过union all,一次性查询了两张表。

对比Sharding-JDBC-4.1.1,对于全局查询,打印的日志如下:

同样是查询tb_order_1和tb_order_2两个表,但是分开两次查询。

小结

以下对比 5.3.0 版本与 4.1.1 的差别:

1)引入的依赖不同,5.3.0 为 shardingsphere-jdbc-core,4.1.1 是sharding-jdbc-spring-boot-starter;

2)配置不同。4.1.1 中的分片策略在application.yml中进行配置,5.3.0 在application.yml中只配置了分片策略的文件路径,分片策略在专门的分片策略文件中配置;

3)5.3.0 相比 4.1.1,提供了许多分片算法。如基于取模的分片算法、基于可变时间范围的分片算法等;

4)5.3.0 相比 4.1.1,某些功能的性能得到了优化;

Shardingsphere文档

YAML 配置 :: ShardingSphere

关于本篇内容你有什么自己的想法或独到见解,欢迎在评论区一起交流探讨下吧。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!