本文最后更新于 2024-04-18,欢迎来到我的Blog! https://www.zpeng.site/

Springboot整合Shardingjdbc实现分库分表

1、介绍

简介

  • Sharding-JDBC定位为轻量级Java框架,在Java的JDBC层提供的额外服务。它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架

  • 市面上常用的 例如 jpa jdbctemplete mybatis mp 原生的 jdbc都是ok的

  • 它对于原有代码的改动很小,无入侵

  • 支持任意实现JDBC规范的数据库,目前支持MySQL,TIDB, Oracle,SQLServer和PostgreSQL

  • 支持分布式事务

  • 支持各种连接池

作用

  • 分库分表: 单库分表,分库后不再分表,分库分表

  • 分布式事务

  • 读写分离

  • 数据库主键生成策略

  • 分库分表路由策略

2、pom.xml

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

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

3、水平单库分表

# 配置文件根节点
server:
  port: 8080  # 服务器端口配置

# Spring应用配置
spring:
  application:
    name: readwritesplitting  # 应用名称
  main:
    allow-bean-definition-overriding: true  # 允许覆盖bean定义
  shardingsphere:  # 分布式数据库相关的配置
    # 属性配置,例如显示SQL
    props:
      sql:
        show: true
    # 数据源配置
    datasource:
      names: master  # 数据源名称
      master:  # 主数据源配置
        # 配置主数据源为Druid
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver  # 数据库驱动类
        url: jdbc:mysql://localhost:3306/master_db?useUnicode=true&characterEncoding=utf-8  # 数据库连接URL
        username: root  # 数据库用户名
        password: root  # 数据库密码
        maxPoolSize: 100  # 最大连接池大小
        minPoolSize: 5  # 最小连接池大小

    # 分片配置
    sharding:
      tables:  # 表的分片配置
        sys_user:   # 表名
          actual-data-nodes: master.sys_user_$->{1..2}  # 实际数据节点,表示在master数据库中,sys_user表会分片为sys_user_1和sys_user_2
          key-generator:  # 分片键生成器
            column: user_id  # 分片键列
            type: SNOWFLAKE  # 分片键生成策略类型,这里使用SNOWFLAKE算法
          table-strategy:  # 表分片策略
            inline:  # 内联分表策略
              algorithm-expression: sys_user_$->{user_id%2+1}  # 算法表达式,根据user_id的值决定数据落在哪个分表
              sharding-column: user_id  # 分片列

# MyBatis配置
mybatis:
  # Mapper XML文件位置
  mapper-locations: classpath:/mapper/*.xml
  configuration:
    # 字段映射配置,将数据库字段的下划线风格转换为Java的驼峰命名风格
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 日志实现方式,这里使用stdout输出日志

4、水平分库分表

# 配置文件根节点
server:
  port: 8080  # 服务器端口配置

# Spring应用配置
spring:
  application:
    name: readwritesplitting  # 应用名称
  main:
    allow-bean-definition-overriding: true  # 允许覆盖bean定义
  shardingsphere:  # 分布式数据库相关的配置
    # 属性配置,例如显示SQL
    props:
      sql:
        show: true
    # 数据源配置
    datasource:
      # 给每个数据源取别名
      names: master1, master2
      # 数据源详细配置,包括主数据库和从数据库
      master1: # 主数据库1配置
        # 配置druid数据源
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/master_db?useUnicode=true&characterEncoding=utf-8
        username: root
        password: root
        maxPoolSize: 100
        minPoolSize: 5

      master2: # 主数据库2配置
        # 配置druid数据源
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/master2_db?useUnicode=true&characterEncoding=utf-8
        username: root
        password: root
        maxPoolSize: 100
        minPoolSize: 5

    # 分片配置
    sharding:
      # 默认执行库
      default-data-source-name: master1
      tables:
        sys_user: # 对应的表配置
          # 实际数据节点
          actual-data-nodes: master$->{1..2}.sys_user$->{1..2}
          # 数据库分片策略
          database-strategy:
            inline:
              algorithm-expression: master$->{user_id % 2 +1}
              sharding-column: user_id
          # 表分片策略
          table-strategy:
            inline:
              algorithm-expression: sys_user$->{user_id % 2 +1}
              sharding-column: user_id
# MyBatis配置
mybatis:
  # Mapper XML文件位置
  mapper-locations: classpath:/mapper/*.xml
  configuration:
    # 字段映射配置
    map-underscore-to-camel-case: true
    # 日志实现方式配置
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

在这个配置中:

spring.shardingsphere.datasource.names 定义了两个数据源的名称,即 master1 和 master2,分别对应实际的两个数据库。

对每个数据源,配置了其具体的 JDBC URL、驱动类名、用户名和密码等信息。

spring.shardingsphere.sharding.tables.sys_user 下面定义了分片表 sys_user 的具体配置:

actual-data-nodes 指定了分片表在各个数据源中的实际分布情况,这里按照 master${0..1}.sys_user${0..1} 的格式表示,表示每个数据库中都有 sys_user0 和 sys_user1 两个分片表。请根据实际的分表数量调整 ${0..1} 范围。

database-strategy 定义了数据库级别的分片策略,采用 inline 简单分片策略,以 user_id 字段作为分片依据,通过 algorithm-expression 设置分片算法表达式,这里使用模运算将用户ID均匀分配到 master1 和 master2 两个数据库。

table-strategy 定义了表级别的分片策略,同样采用 inline 简单分片策略,以 user_id 字段作为分片依据,通过 algorithm-expression 设置分片算法表达式,这里使用模运算将用户ID均匀分配到 sys_user0 和 sys_user1 两个表。

spring.shardingsphere.props.sql.show 是可选配置项,用于控制是否打印 SQL 执行语句,有助于调试。

请确保在应用这些配置之前,已经手动创建好 master1 和 master2 数据库以及它们内部的分片表结构(如 sys_user0 和 sys_user1)。同时,根据实际业务需求调整分片策略中的算法表达式,以达到期望的分库分表效果。