SpringBoot集成ShardingSphere-JDBC實(shí)現(xiàn)分庫(kù)分表
前言:該文章目前只基本實(shí)現(xiàn)分庫(kù)分表,如需更復(fù)雜功能請(qǐng)移步官方文檔,后續(xù)會(huì)出復(fù)雜實(shí)現(xiàn)的筆記,如有需要請(qǐng)關(guān)注留言
一、ShardingSphere-JDBC 概述
作用之一:實(shí)現(xiàn)分庫(kù)分表存儲(chǔ)
ShardingSphere-JDBC 是 Apache ShardingSphere 的輕量級(jí)解決方案,定位為增強(qiáng)型 JDBC 驅(qū)動(dòng)。它以 jar 包形式存在于應(yīng)用程序中,通過(guò)實(shí)現(xiàn) DataSource 接口,對(duì)上層應(yīng)用提供透明的分庫(kù)分表能力,與應(yīng)用程序共享同一個(gè) JVM 進(jìn)程。
1. 核心特性
- 分庫(kù)分表:支持水平分庫(kù)、水平分表、垂直分庫(kù)等多種分片模式。
 - 讀寫分離:支持主從復(fù)制架構(gòu)下的讀寫分離。
 - 分布式事務(wù):提供 XA 和柔性事務(wù)支持。
 - 數(shù)據(jù)加密:支持敏感數(shù)據(jù)透明加密。
 - 影子庫(kù):支持灰度發(fā)布和數(shù)據(jù)驗(yàn)證。
 
2. 與其他中間件對(duì)比
| 類型 | 優(yōu)點(diǎn) | 缺點(diǎn) | 
|---|---|---|
| ShardingSphere-JDBC | 無(wú)額外部署成本,輕量級(jí),性能損耗小 | 與應(yīng)用綁定,升級(jí)維護(hù)需修改代碼 | 
| ShardingSphere-Proxy | 對(duì)應(yīng)用透明,支持異構(gòu)語(yǔ)言,獨(dú)立部署 | 需要額外運(yùn)維,性能略低于 JDBC | 
| MyCat/Atlas | 成熟穩(wěn)定,社區(qū)活躍 | 功能不如 ShardingSphere 全面 | 
二、集成前項(xiàng)目架構(gòu)(單數(shù)據(jù)源)
1. 依賴配置
<!-- MyBatis-Plus 依賴 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.3.4</version> </dependency> <!-- HikariCP 連接池 --> <dependency> <groupId>com.zaxxer</groupId> <artifactId>hikari-cp</artifactId> </dependency> <!-- MySQL 驅(qū)動(dòng) --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency>
2.配置文件 (application.yml)
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/enterprise_practical_project
    username: root
    password: qwer123456
    hikari:
      maximum-pool-size: 15
      minimum-idle: 5
      connection-timeout: 30000
mybatis-plus:
  mapper-locations: classpath:cn/jjcoder/mapper/*.xml
  type-aliases-package: cn.jjcoder.entity
  configuration:
    map-underscore-to-camel-case: true
3. MyBatis-Plus 配置類
@Configuration
public class MyBatisPlusConfig {
    //插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
        factory.setDataSource(dataSource);
        factory.setMapperLocations(new PathMatchingResourcePatternResolver()
                                   .getResources("classpath:cn/jjcoder/mapper/*.xml"));
        return factory.getObject();
    }
}
4. 架構(gòu)特點(diǎn)
- 應(yīng)用直接連接單一數(shù)據(jù)庫(kù)。
 - MyBatis-Plus 直接管理數(shù)據(jù)源。
 - 所有表存儲(chǔ)在同一個(gè)數(shù)據(jù)庫(kù)實(shí)例中。
 
三、集成后項(xiàng)目架構(gòu)(ShardingSphere-JDBC)
1. 新增依賴
<!-- ShardingSphere-JDBC 核心依賴 -->
<!-- https://mvnrepository.com/artifact/org.apache.shardingsphere/sharding-jdbc-spring-boot-starter -->
<dependency>
  <groupId>org.apache.shardingsphere</groupId>
  <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
  <version>5.1.2</version>
  <exclusions>
    <!-- 排除Druid自動(dòng)配置 -->
    <exclusion>
      <groupId>com.alibaba</groupId>
      <artifactId>druid-spring-boot-starter</artifactId>
    </exclusion>
    <!-- 排除任務(wù)調(diào)度器 -->
    <exclusion>
      <groupId>org.apache.shardingsphere</groupId>
      <artifactId>shardingsphere-schedule-core</artifactId>
    </exclusion>
  </exclusions>
</dependency>
2. 配置文件變更
spring:
    shardingsphere:
    # 公共數(shù)據(jù)源配置(錨點(diǎn))
    common-ds: &common-ds
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.cj.jdbc.Driver
      username: root
      password: qwer123456
      hikari:
        minimum-idle: 5
        maximum-pool-size: 15
        idle-timeout: 30000
    datasource:
      names: main_db,ds2025
      main_db:
        <<: *common-ds  # 引用公共配置
        jdbc-url: jdbc:mysql://localhost:3306/enterprise_practical_project
      ds2025:
        <<: *common-ds
        jdbc-url: jdbc:mysql://localhost:3306/shard_db_2025
#      ds2026:
#        <<: *common-ds
#        jdbc-url: jdbc:mysql://localhost:3306/shard_db_2026
    rules:
      sharding:
        tables:
          standing_book:
            actual-data-nodes: ds$->{2025..2026}.standing_book_$->{202501..202512}
            database-strategy:
              standard:
                sharding-column: in_out_date
                sharding-algorithm-name: db-interval
            table-strategy:
              standard:
                sharding-column: in_out_date
                sharding-algorithm-name: table-interval
        sharding-algorithms:
          db-interval:
            type: INTERVAL
            props:
              datetime-pattern: "yyyy-MM-dd"
              datetime-lower: '2025-01-01'
              datetime-upper: '2026-12-31'
              sharding-suffix-pattern: 'yyyy'
              datetime-interval-amount: 1
              datetime-interval-unit: years
          table-interval:
            type: INTERVAL
            props:
              datetime-pattern: "yyyy-MM-dd"
              datetime-lower: '2025-01-01'
              datetime-upper: '2026-12-31'
              sharding-suffix-pattern: 'yyyyMM'
              datetime-interval-amount: 1
              datetime-interval-unit: months
              datetime-format-pattern: ^\d{4}-\d{2}-\d{2}$
    
mybatis-plus:
  mapper-scan:
    base-package: cn.jjcoder.mapper
  global-config:
    db-config:
      logic-delete-field: deleted # 全局邏輯刪除字段名
      logic-delete-value: 1 # 邏輯已刪除值
      logic-not-delete-value: 0 # 邏輯未刪除值
  configuration:
    # 配置下劃線與駝峰之間轉(zhuǎn)換
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath:cn.jjcoder.mapper/*.xml
  type-aliases-package: cn.jjcoder.entity
    
3. MyBatis-Plus 配置類
@Configuration
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);// 注入的是 ShardingSphere 的數(shù)據(jù)源
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                                          .getResources("classpath:cn/jjcoder/mapper/*.xml"));
        return sessionFactory.getObject();
    }
    /**
     * 使用 ShardingSphere 時(shí),事務(wù)管理器需要指向 ShardingSphere 的數(shù)據(jù)源:
     * @param dataSource
     * @return
     */
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}
4. 架構(gòu)特點(diǎn)
- 應(yīng)用通過(guò) ShardingSphere-JDBC 連接多個(gè)數(shù)據(jù)庫(kù)。
 - ShardingSphere 管理多個(gè)物理數(shù)據(jù)源,向上層(MP)提供統(tǒng)一的邏輯數(shù)據(jù)源。
 - MyBatis-Plus 操作 ShardingSphere 提供的邏輯數(shù)據(jù)源,無(wú)需感知底層分片細(xì)節(jié)。
 - 分片規(guī)則完全由 ShardingSphere 配置控制。
 
四、集成后效果演示
通過(guò)插入數(shù)據(jù)來(lái)演示 mybatis-plus 和ShardingSphere之間的工作流程分庫(kù)分表
前言:我目前在 application.yml 配置文件中配置的需要分庫(kù)分表的表為 standing_book(臺(tái)賬表),并且配好了多數(shù)據(jù)源的連接信息,以及具體的分片算法。所以在此之前需要保證數(shù)據(jù)庫(kù)有相應(yīng)的庫(kù)和表,以及表的分片鍵類型(這點(diǎn)我在剛開始做的時(shí)候沒(méi)注意,后續(xù)出了bug排查了好久)
保證以上之后,演示分庫(kù)分表具體效果:
由于分庫(kù)分表的表為standing_book,所以需給這個(gè)表插入數(shù)據(jù)才能觸發(fā),目前我的業(yè)務(wù)邏輯為 產(chǎn)品出入庫(kù)時(shí)生成臺(tái)賬信息保存數(shù)據(jù)庫(kù)
- 往 standing_book 插入數(shù)據(jù)代碼
 
/**
     * 根據(jù)商品出入庫(kù)生成臺(tái)賬
     * @param list
     * @return
     */
    @Override
    public boolean saveByProductInOrOut(List<ProductVO> list, String userName, boolean isIn) {
        String operationType = isIn ? "入庫(kù)" : "出庫(kù)";
        List<StandingBook> standingBooks = new ArrayList<>();
        for (ProductVO vo : list) {
            StandingBook standingBook = new StandingBook();
            standingBook.setProductId(vo.getId());   //產(chǎn)品id
            standingBook.setProductName(vo.getName()); //產(chǎn)品名稱
            standingBook.setOperationType(operationType);  //操作類型
            standingBook.setOperationNum(vo.getInOrOutCount());  //入庫(kù)or出庫(kù)數(shù)量
            Integer newQuantity=isIn? vo.getInventory()+vo.getInOrOutCount() : vo.getInventory()-vo.getInOrOutCount();
            standingBook.setNewQuantity(newQuantity);  //出入庫(kù)后庫(kù)存總量
            standingBook.setOrperator(userName);
            standingBook.setCreateDatetime(LocalDateTime.now());
            standingBook.setInOutDate(LocalDate.now().toString());  //設(shè)置分片鍵值(shardingsphere會(huì)根據(jù)該字段值進(jìn)行分片,路由到相應(yīng)的庫(kù)表)
            standingBooks.add(standingBook);
        }
        //該 saveOrUpdateBatchCustom 將會(huì)觸發(fā)分庫(kù)分表算法
        return this.saveOrUpdateBatchCustom(standingBooks);
    }
- 控制臺(tái)執(zhí)行信息如下
 
# mybatis-plus生成的sql
2025-05-20 20:06:48.308 DEBUG --- [onPool-worker-9] c.j.mapper.StandingBookMapper.insert     : ==>  Preparing: INSERT INTO standing_book ( standing_book_id, product_id, product_name, operation_type, in_out_date, orperator, operation_num, new_quantity, create_datetime ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )
2025-05-20 20:06:48.316 DEBUG --- [onPool-worker-9] c.j.mapper.StandingBookMapper.insert     : ==> Parameters: f1feb93be82375630ce8f4c3a8e006f8(String), 1dbcf56794cc1cc21ea12719ea7b7a86(String), 6(String), 入庫(kù)(String), 2025-05-20(String), root(String), 1(Integer), 35(Integer), 2025-05-20T20:06:48.307(LocalDateTime)
                                                                                                                                                                                                                                                                                                             # 被ShardingSphere接管()
                                                                                                                                                                                                                                                                                                             # 邏輯sql
2025-05-20 20:06:48.322  INFO --- [onPool-worker-9] ShardingSphere-SQL                       : Logic SQL: INSERT INTO standing_book  ( standing_book_id,
                                                                                                                                       product_id,
                                                                                                                                       product_name,
                                                                                                                                       operation_type,
                                                                                                                                       in_out_date,
                                                                                                                                       orperator,
                                                                                                                                       operation_num,
                                                                                                                                       new_quantity,
                                                                                                                                       create_datetime )  VALUES  ( ?,
?,
?,
?,
?,
?,
?,
?,
? )
2025-05-20 20:06:48.322  INFO --- [onPool-worker-9] ShardingSphere-SQL                       : SQLStatement: MySQLInsertStatement(setAssignment=Optional.empty, onDuplicateKeyColumns=Optional.empty)
# 實(shí)際執(zhí)行sql
2025-05-20 20:06:48.322  INFO --- [onPool-worker-9] ShardingSphere-SQL                       : Actual SQL: ds2025 ::: INSERT INTO standing_book_202505  ( standing_book_id,
                                                                                                                                                          product_id,
                                                                                                                                                          product_name,
                                                                                                                                                          operation_type,
                                                                                                                                                          in_out_date,
                                                                                                                                                          orperator,
                                                                                                                                                          operation_num,
                                                                                                                                                          new_quantity,
                                                                                                                                                          create_datetime )  VALUES  (?, ?, ?, ?, ?, ?, ?, ?, ?) ::: [f1feb93be82375630ce8f4c3a8e006f8, 1dbcf56794cc1cc21ea12719ea7b7a86, 6, 入庫(kù), 2025-05-20, root, 1, 35, 2025-05-20T20:06:48.307]
通過(guò)以上控制臺(tái)輸出可以看到
- mybatis-plus依舊會(huì)生成預(yù)編譯sql,但是被shardingsphere接管
 - 可以看到 shardingsphere 的邏輯sql 和實(shí)際執(zhí)行sql
- 實(shí)際執(zhí)行sql上顯示了具體路由到的庫(kù)和表
 
 

具體執(zhí)行流程如下:
- 應(yīng)用代碼調(diào)用:Service 層調(diào)用 Mapper 接口方法。
 - MyBatis-Plus 處理:
■ 通過(guò) SqlSessionFactory 獲取 SqlSession。
■ 生成 SQL 語(yǔ)句。 - ShardingSphere 攔截:
■ ShardingDataSource 攔截 SQL 執(zhí)行請(qǐng)求。
■ 根據(jù)分片規(guī)則計(jì)算目標(biāo)庫(kù)表。
■ 路由 SQL 到對(duì)應(yīng)的物理數(shù)據(jù)源和表。 - 數(shù)據(jù)庫(kù)執(zhí)行:實(shí)際執(zhí)行 SQL 并返回結(jié)果。
 - 結(jié)果返回:結(jié)果通過(guò) ShardingSphere 封裝后返回給 MyBatis-Plus,MyBatis-Plus 將結(jié)果映射為 Java 對(duì)象返回給應(yīng)用。
 
五、配置加載與協(xié)作流程
1. 配置加載順序
- Spring Boot 啟動(dòng):加載 application.yml 配置文件。
 - ShardingSphere 自動(dòng)配置:
- ShardingSphereAutoConfiguration 類解析 spring.shardingsphere 配置。
 - 創(chuàng)建多個(gè)物理數(shù)據(jù)源(HikariCP 連接池)。
 - 根據(jù)分片規(guī)則創(chuàng)建 ShardingDataSource(實(shí)現(xiàn) DataSource 接口)。
 - 將 ShardingDataSource 注冊(cè)為 Spring 容器中的唯一 DataSource Bean。
 
 - MyBatis-Plus 自動(dòng)配置:
- MybatisPlusAutoConfiguration 類自動(dòng)加載。
 - 注入 ShardingSphere 提供的 DataSource Bean。
 - 創(chuàng)建 SqlSessionFactory 和其他 MyBatis 組件。
 
 
2. 核心組件初始化過(guò)程
ShardingSphere 初始化:
ShardingSphereAutoConfiguration → 解析配置文件 → 創(chuàng)建多個(gè) HikariDataSource 實(shí)例 → 根據(jù)分片規(guī)則創(chuàng)建 ShardingRule → 將數(shù)據(jù)源和規(guī)則組裝為 ShardingDataSource → 注冊(cè) ShardingDataSource 到 Spring 容器
MyBatis-Plus 初始化:
MybatisPlusAutoConfiguration → 從 Spring 容器獲取唯一的 DataSource Bean(即 ShardingDataSource) → 創(chuàng)建 MybatisSqlSessionFactoryBean → 設(shè)置數(shù)據(jù)源、映射文件路徑等配置 → 初始化 SqlSessionFactory → 注冊(cè) MyBatis 的 MapperScanner
3. SQL 執(zhí)行協(xié)作流程
- 應(yīng)用代碼調(diào)用:Service 層調(diào)用 Mapper 接口方法。
 - MyBatis-Plus 處理:
- 通過(guò) SqlSessionFactory 獲取 SqlSession。
 - 生成 SQL 語(yǔ)句。
 
 - ShardingSphere 攔截:
- ShardingDataSource 攔截 SQL 執(zhí)行請(qǐng)求。
 - 根據(jù)分片規(guī)則計(jì)算目標(biāo)庫(kù)表。
 - 路由 SQL 到對(duì)應(yīng)的物理數(shù)據(jù)源和表。
 
 - 數(shù)據(jù)庫(kù)執(zhí)行:實(shí)際執(zhí)行 SQL 并返回結(jié)果。
 - 結(jié)果返回:結(jié)果通過(guò) ShardingSphere 封裝后返回給 MyBatis-Plus,MyBatis-Plus 將結(jié)果映射為 Java 對(duì)象返回給應(yīng)用。
 
六、集成前后代碼對(duì)比
1. 依賴對(duì)比
- 集成前
- 項(xiàng)目?jī)H依賴 MyBatis-Plus、HikariCP 連接池和 MySQL 驅(qū)動(dòng),聚焦于單數(shù)據(jù)源下的數(shù)據(jù)庫(kù)操作與對(duì)象關(guān)系映射。
 
 - 而集成 ShardingSphere-JDBC 后
- 新增了 ShardingSphere-JDBC 核心依賴,此依賴引入分庫(kù)分表等關(guān)鍵功能,使得項(xiàng)目具備處理多數(shù)據(jù)源和復(fù)雜數(shù)據(jù)分布的能力。
 
 
| 對(duì)比維度 | 集成前 | 集成后 | 
|---|---|---|
| 核心依賴變化 | 僅包含 MyBatis-Plus 及基礎(chǔ)數(shù)據(jù)庫(kù)連接依賴 | 新增 ShardingSphere-JDBC 核心依賴,構(gòu)建多數(shù)據(jù)源處理能力 | 
| 功能擴(kuò)展 | 支持單數(shù)據(jù)源下的常規(guī)數(shù)據(jù)庫(kù)操作與對(duì)象映射 | 新增分庫(kù)分表、讀寫分離、分布式事務(wù)等高級(jí)功能 | 
2. 配置文件對(duì)比
在數(shù)據(jù)源配置部分
- 集成前
- 采用傳統(tǒng)的 spring.datasource 配置單一數(shù)據(jù)源,簡(jiǎn)潔明了地定義驅(qū)動(dòng)、URL、用戶名和密碼等信息。
 
 - 集成后,
- 數(shù)據(jù)源配置轉(zhuǎn)移到 spring.shardingsphere.datasource 下,不僅需定義多個(gè)物理數(shù)據(jù)源,還需配置各數(shù)據(jù)源的詳細(xì)參數(shù),如連接池設(shè)置。
 - 此外,新增的 spring.shardingsphere.rules 用于配置復(fù)雜的分庫(kù)分表規(guī)則,涵蓋數(shù)據(jù)節(jié)點(diǎn)分布、分片策略和算法,以實(shí)現(xiàn)數(shù)據(jù)的合理分片存儲(chǔ)與高效訪問(wèn)。
 
 
| 對(duì)比維度 | 集成前 | 集成后 | 
|---|---|---|
| 數(shù)據(jù)源配置位置 | spring.datasource,配置單一數(shù)據(jù)源 | spring.shardingsphere.datasource,配置多個(gè)物理數(shù)據(jù)源 | 
| 配置復(fù)雜度 | 簡(jiǎn)單定義驅(qū)動(dòng)、URL、用戶名和密碼等基本信息 | 除基本信息外,還需配置多個(gè)數(shù)據(jù)源連接池參數(shù),以及分庫(kù)分表規(guī)則 | 
| 新增配置項(xiàng) | 無(wú) | spring.shardingsphere.rules,用于定義分庫(kù)分表規(guī)則,包括數(shù)據(jù)節(jié)點(diǎn)、分片策略和算法 | 
3. 代碼邏輯對(duì)比
從數(shù)據(jù)訪問(wèn)層代碼邏輯來(lái)看
- 集成前
- MyBatis-Plus 直接操作單一數(shù)據(jù)源,開發(fā)人員無(wú)需關(guān)注數(shù)據(jù)源的復(fù)雜性,可專注于業(yè)務(wù) SQL 編寫和對(duì)象映射。
 
 - 集成后
- 雖然 MyBatis-Plus 的 Mapper 接口和業(yè)務(wù)代碼在形式上未發(fā)生明顯變化,但實(shí)際上,MyBatis-Plus 操作的已變?yōu)?ShardingSphere 提供的邏輯數(shù)據(jù)源。
 - ShardingSphere 會(huì)在底層自動(dòng)處理 SQL 路由,根據(jù)分庫(kù)分表規(guī)則將 SQL 準(zhǔn)確發(fā)送到對(duì)應(yīng)的物理數(shù)據(jù)源和表,開發(fā)人員無(wú)需手動(dòng)處理復(fù)雜的路由邏輯,降低了開發(fā)難度和出錯(cuò)概率。
 
 
| 對(duì)比維度 | 集成前 | 集成后 | 
|---|---|---|
| 數(shù)據(jù)訪問(wèn)方式 | MyBatis-Plus 直接操作單一數(shù)據(jù)源,簡(jiǎn)單直觀 | MyBatis-Plus 操作 ShardingSphere 提供的邏輯數(shù)據(jù)源,底層自動(dòng)處理 SQL 路由 | 
| 開發(fā)關(guān)注點(diǎn) | 專注于業(yè)務(wù) SQL 編寫和對(duì)象映射 | 無(wú)需關(guān)注復(fù)雜的 SQL 路由邏輯,專注業(yè)務(wù)邏輯,由 ShardingSphere 處理數(shù)據(jù)分片 | 
| 代碼改動(dòng) | 無(wú)明顯代碼改動(dòng) | 無(wú)明顯代碼改動(dòng),僅配置變化,對(duì)業(yè)務(wù)代碼透明 | 
4. 架構(gòu)設(shè)計(jì)對(duì)比
在架構(gòu)層面
- 集成前
- 項(xiàng)目架構(gòu)簡(jiǎn)單,應(yīng)用與單一數(shù)據(jù)庫(kù)直接相連,數(shù)據(jù)處理邏輯集中在單庫(kù)內(nèi),適用于數(shù)據(jù)規(guī)模較小、業(yè)務(wù)邏輯相對(duì)簡(jiǎn)單的場(chǎng)景。
 
 - 集成后
- 引入 ShardingSphere-JDBC 使架構(gòu)轉(zhuǎn)變?yōu)閼?yīng)用通過(guò) ShardingSphere 連接多個(gè)數(shù)據(jù)庫(kù),形成分布式數(shù)據(jù)存儲(chǔ)架構(gòu)。
 - ShardingSphere 作為中間層,管理多個(gè)物理數(shù)據(jù)源,向上提供統(tǒng)一的邏輯數(shù)據(jù)源,實(shí)現(xiàn)數(shù)據(jù)的分布式存儲(chǔ)與訪問(wèn),提升了系統(tǒng)的擴(kuò)展性和性能,以應(yīng)對(duì)大規(guī)模數(shù)據(jù)和高并發(fā)訪問(wèn)的挑戰(zhàn)。
 
 
| 對(duì)比維度 | 集成前 | 集成后 | 
|---|---|---|
| 數(shù)據(jù)庫(kù)連接關(guān)系 | 應(yīng)用直接連接單一數(shù)據(jù)庫(kù),架構(gòu)簡(jiǎn)單 | 應(yīng)用通過(guò) ShardingSphere-JDBC 連接多個(gè)數(shù)據(jù)庫(kù),形成分布式架構(gòu) | 
| 數(shù)據(jù)管理方式 | 單庫(kù)內(nèi)數(shù)據(jù)處理,邏輯集中 | ShardingSphere 管理多個(gè)物理數(shù)據(jù)源,實(shí)現(xiàn)數(shù)據(jù)分片存儲(chǔ)與統(tǒng)一訪問(wèn) | 
| 架構(gòu)擴(kuò)展性 | 擴(kuò)展性有限,難以應(yīng)對(duì)大規(guī)模數(shù)據(jù)和高并發(fā) | 擴(kuò)展性增強(qiáng),可通過(guò)增加數(shù)據(jù)源應(yīng)對(duì)數(shù)據(jù)增長(zhǎng)和高并發(fā)需求 | 
七、關(guān)鍵注意事項(xiàng)
1. 數(shù)據(jù)源唯一性
(以下配置如果你是以代碼形式配置數(shù)據(jù)源的話這么配置,如果是在application.yml中配置需在配置文件配置)
確保 Spring 容器中只有一個(gè) DataSource Bean,即 ShardingSphere 提供的 ShardingDataSource。如果存在多個(gè) DataSource Bean,需要通過(guò) @Primary 注解明確指定主數(shù)據(jù)源。
若項(xiàng)目中存在多個(gè)數(shù)據(jù)源配置,需顯式指定 ShardingSphere 的數(shù)據(jù)源為主要數(shù)據(jù)源:
示例代碼
@Configuration
public class DataSourceConfig {
    // 假設(shè)存在多個(gè)數(shù)據(jù)源 Bean
    @Bean
    @Primary // 指定 ShardingSphere 的數(shù)據(jù)源為主要數(shù)據(jù)源
    public DataSource shardingDataSource() throws SQLException {
        // 從 ShardingSphere 配置構(gòu)建數(shù)據(jù)源
        return ShardingSphereDataSourceFactory.createDataSource(createShardingRuleConfiguration());
    }
    // 其他數(shù)據(jù)源 Bean(非主要)
    @Bean
    public DataSource anotherDataSource() {
        // 配置其他數(shù)據(jù)源
        return DataSourceBuilder.create().build();
    }
    // 構(gòu)建 ShardingSphere 分片規(guī)則配置
    private ShardingRuleConfiguration createShardingRuleConfiguration() {
        // 配置分片規(guī)則...
    }
}
2. 事務(wù)管理
在使用ShardingSphere的分布式事務(wù)支持時(shí),可通過(guò)配置事務(wù)類型屬性來(lái)選擇事務(wù)模式。例如,若采用XA強(qiáng)一致性事務(wù),可在application.yml中添加spring.shardingsphere.props.transaction.type=XA配置;若選擇柔性事務(wù)(如基于最大努力送達(dá)型的事務(wù)),則需結(jié)合具體業(yè)務(wù)場(chǎng)景,合理配置補(bǔ)償策略和消息隊(duì)列等組件,確保事務(wù)最終一致性。
對(duì)于跨庫(kù)事務(wù),需要使用分布式事務(wù)管理器,如 Seata 或 ShardingSphere 自身提供的分布式事務(wù)支持:
spring:
  shardingsphere:
    props:
      xa-transaction-manager-type: atomikos  # 使用 Atomikos XA 事務(wù)管理器
3. SQL 限制
分庫(kù)分表場(chǎng)景下,部分復(fù)雜 SQL 可能無(wú)法執(zhí)行,如:
- 跨庫(kù)關(guān)聯(lián)查詢。
 - 跨庫(kù)聚合函數(shù)(如 COUNT、SUM)。
 - 分布式主鍵生成。
 
4. 性能監(jiān)控
ShardingSphere 提供內(nèi)置的 SQL 監(jiān)控功能,可以通過(guò)配置開啟:
spring:
  shardingsphere:
    props:
      sql-show: true  # 打印 SQL
      metrics-name: prometheus  # 集成 Prometheus 監(jiān)控
八、常見問(wèn)題與解決方案
1. 啟動(dòng)時(shí)報(bào) “SqlSessionFactory 找不到”
在 MybatisPlusConfig 配置如下bean
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
    sessionFactory.setDataSource(dataSource);
    sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                                      .getResources("classpath:cn/jjcoder/mapper/*.xml"));
    return sessionFactory.getObject();
}2. SQL 執(zhí)行異常,表不存在
- 原因:分片規(guī)則配置錯(cuò)誤,SQL 路由到不存在的表。
 - 解決方案:
- 檢查 
actual-data-nodes配置是否正確。 - 確認(rèn)分片算法和分片鍵配置是否匹配。
 - 確保 
actual-data-nodes中的表名與實(shí)際數(shù)據(jù)庫(kù)中的表名一致: 
 - 檢查 
 
3. 事務(wù)不生效
- 原因:跨庫(kù)事務(wù)需要分布式事務(wù)支持。
 - 解決方案:
- 配置分布式事務(wù)管理器(如 Atomikos、Seata)。
 - 使用 
@Transactional注解時(shí)指定正確的事務(wù)管理器。 
 
配置文件修改示例:
配置 Atomikos XA 事務(wù)管理器:
spring:
 shardingsphere:
   props:
     xa-transaction-manager-type: atomikos # 啟用 XA 事務(wù)Java 配置示例:
定義分布式事務(wù)管理器:
@Configuration
public class TransactionConfig {
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        // 使用 Atomikos 分布式事務(wù)管理器
        JtaTransactionManager transactionManager = new JtaTransactionManager();
        transactionManager.setTransactionManager(new UserTransactionManager());
        transactionManager.setUserTransaction(new UserTransactionImp());
        return transactionManager;
    }
}
4. 性能下降明顯
- 原因:分片規(guī)則不合理或連接池配置不當(dāng)。
 - 解決方案:
- 優(yōu)化分片算法,避免數(shù)據(jù)傾斜。
 - 調(diào)整連接池參數(shù)(如 
maximum-pool-size)。 - 開啟 SQL 監(jiān)控,分析慢查詢。
 
 
配置文件修改示例:
優(yōu)化 HikariCP 連接池參數(shù):
spring:
   shardingsphere:
    # 公共數(shù)據(jù)源配置(錨點(diǎn))
    common-ds: &common-ds
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.cj.jdbc.Driver
      username: root
      password: qwer123456
      hikari:
        maximum-pool-size: 30 # 增加最大連接數(shù)
        minimum-idle: 10 # 增加最小空閑連接數(shù)
        idle-timeout: 30000 # 空閑連接超時(shí)時(shí)間
        max-lifetime: 1800000 # 連接最大生命周期
九、總結(jié)
通過(guò)集成 ShardingSphere-JDBC,我們?cè)诓恍薷?MyBatis-Plus 代碼的前提下,實(shí)現(xiàn)了數(shù)據(jù)庫(kù)的分庫(kù)分表能力。這種架構(gòu)既保留了 MyBatis-Plus 的開發(fā)便利性,又通過(guò) ShardingSphere 提升了系統(tǒng)的可擴(kuò)展性和性能。關(guān)鍵要點(diǎn)包括:
- ShardingSphere-JDBC 作為增強(qiáng)型 JDBC 驅(qū)動(dòng),對(duì)上層應(yīng)用透明。
 - 集成后,MyBatis-Plus 操作的是 ShardingSphere 提供的邏輯數(shù)據(jù)源,無(wú)需關(guān)心底層分片細(xì)節(jié)。
 - 分片規(guī)則完全通過(guò)配置文件控制,無(wú)需修改 DAO 層代碼。
 - 需要注意分布式事務(wù)、復(fù)雜 SQL 支持等特殊
 
到此這篇關(guān)于SpringBoot集成ShardingSphere-JDBC實(shí)現(xiàn)分庫(kù)分表的文章就介紹到這了,更多相關(guān)ShardingSphere-JDBC分庫(kù)分表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
 springboot2?使用activiti6?idea插件的過(guò)程詳解
這篇文章主要介紹了springboot2?使用activiti6?idea插件,本文通過(guò)截圖實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
 Spring定時(shí)任務(wù)只執(zhí)行一次的原因分析與解決方案
在使用Spring的@Scheduled定時(shí)任務(wù)時(shí),你是否遇到過(guò)任務(wù)只執(zhí)行一次,后續(xù)不再觸發(fā)的情況?這種情況可能由多種原因?qū)е?如未啟用調(diào)度、線程池問(wèn)題、異常中斷等,本文將深入分析Spring定時(shí)任務(wù)只執(zhí)行一次的原因,并提供完整的解決方案,需要的朋友可以參考下2025-03-03
 Java的Socket網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)入門教程
這篇文章主要介紹了Java的Socket網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)入門教程,包括基于TCP/IP和UDP協(xié)議的簡(jiǎn)單實(shí)例程序講解,需要的朋友可以參考下2016-01-01
 FeignClient如何共享Header及踩坑過(guò)程記錄
這篇文章主要介紹了FeignClient如何共享Header及踩坑過(guò)程記錄,2022-03-03
 SpringBoot圖文并茂講解Lombok庫(kù)的安裝與使用
Lombok想要解決了的是在我們實(shí)體Bean中大量的Getter/Setter方法,以及toString, hashCode等可能不會(huì)用到,但是某些時(shí)候仍然需要復(fù)寫,以期方便使用的方法;在使用Lombok之后,將由其來(lái)自動(dòng)幫你實(shí)現(xiàn)代碼生成2022-06-06
 Java控制臺(tái)版五子棋的簡(jiǎn)單實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于Java控制臺(tái)版五子棋的簡(jiǎn)單實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
 mybatis-plus配置日志兩種實(shí)現(xiàn)方式
這篇文章主要給大家介紹了關(guān)于mybatis-plus配置日志兩種實(shí)現(xiàn)方式的相關(guān)資料,Mybatis-plus集成了日志框架,可以將程序運(yùn)行時(shí)產(chǎn)生的日志進(jìn)行記錄,方便開發(fā)人員進(jìn)行問(wèn)題排查,需要的朋友可以參考下2023-09-09

