天天看點

Spring Boot demo系列(十三):ShardingSphere + MyBatisPlus 分庫分表1 概述2 準備資料庫環境3 建立項目4 配置檔案5 測試代碼生成6 增加雪花id生成器7 測試8 參考源碼

1 概述

本文主要講述了如何使用

ShardingSphere

(其中的

Sharding-JDBC

)和

MyBatisPlus

進行分庫分表,具體步驟包括:

  • 準備資料庫環境
  • 準備依賴
  • 編寫配置檔案
  • 測試

2 準備資料庫環境

2.1 兩庫六表

準備好兩個庫:

  • test0

  • test1

在兩個庫中分别建立三個字段一樣的表:

  • user0

  • user1

  • user2

Spring Boot demo系列(十三):ShardingSphere + MyBatisPlus 分庫分表1 概述2 準備資料庫環境3 建立項目4 配置檔案5 測試代碼生成6 增加雪花id生成器7 測試8 參考源碼

字段如下:

Spring Boot demo系列(十三):ShardingSphere + MyBatisPlus 分庫分表1 概述2 準備資料庫環境3 建立項目4 配置檔案5 測試代碼生成6 增加雪花id生成器7 測試8 參考源碼

這樣就準備了兩個庫以及其中的六個表了。

2.2 (可選)

MyBatis Plus Generator

代碼生成表

因為

MyBatis Plus Generator

生成的

Controller

等代碼預設是按照表名命名的,這樣就會生成類似

User0

User0Controller

這樣的命名,是以這裡建立一個叫

user

的表,僅僅用于代碼的生成,裡面不會存放任何的資料:

Spring Boot demo系列(十三):ShardingSphere + MyBatisPlus 分庫分表1 概述2 準備資料庫環境3 建立項目4 配置檔案5 測試代碼生成6 增加雪花id生成器7 測試8 參考源碼

3 建立項目

建立

Spring Boot

項目并引入如下依賴:

  • Druid

  • MyBatis Plus starter

  • MyBaits Plus Generator

  • Velocity core

  • ShardingSphere

  • Yitter

    (一個雪花

    id

    生成器)

Maven

如下:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.3.1</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.0</version>
</dependency>
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.3</version>
</dependency>
<dependency>
    <groupId>org.realityforge.org.jetbrains.annotations</groupId>
    <artifactId>org.jetbrains.annotations</artifactId>
    <version>1.7.0</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.6</version>
</dependency>
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.1.1</version>
</dependency>
<dependency>
    <groupId>com.github.yitter</groupId>
    <artifactId>yitter-idgenerator</artifactId>
    <version>1.0.6</version>
</dependency>
           

Gradle

如下:

implementation 'com.baomidou:mybatis-plus-boot-starter:3.4.3.1'
implementation 'org.apache.velocity:velocity-engine-core:2.3'
implementation 'org.realityforge.org.jetbrains.annotations:org.jetbrains.annotations:1.7.0'
implementation 'com.alibaba:druid:1.2.6'
implementation 'org.apache.shardingsphere:sharding-jdbc-spring-boot-starter:4.1.1'
implementation 'com.github.yitter:yitter-idgenerator:1.0.6'
           

4 配置檔案

配置檔案可以參考ShardingSphere文檔,這裡給出一個示例配置:

spring:
  shardingsphere:
    datasource:
      names: test0,test1                                        # 資料源,這裡為了友善直接使用庫名的名稱
      test0:                                                   
        type: com.alibaba.druid.pool.DruidDataSource            # Druid連接配接池
        url: jdbc:mysql://127.0.0.1:3306/test0                  # 連接配接test0的url
        username: root
        password: 123456
      test1:
        type: com.alibaba.druid.pool.DruidDataSource            # Druid連接配接池
        url: jdbc:mysql://127.0.0.1:3306/test1                  # 連接配接test1的url
        username: root
        password: 123456
    sharding:
      default-database-strategy:                                # 預設分庫政策
        inline:  
          sharding-column: age                                  # 表示根據age列進行分庫
          algorithm-expression: test$->{age % 2}                # 根據age對2的模進行分庫,模為0表示test0庫,模為1表示test1庫
      tables:
        user:
          actual-data-nodes: test$->{0..1}.user$->{0..2}        # 表的名字,test$->{0..1}可以表示test0、test1兩個庫
                                                                # user$->{0..2}表示user0、user1、user2三個庫
          table-strategy:                                       # 分表政策
            inline:
              sharding-column: id                               # 根據哪一列進行分表,id表示根據列名為"id"的列分表
              algorithm-expression: user$->{id%3}               # 分表規則為id對3取模,id%3為0表示分到user0表
                                                                # id%3為1表示分到user1表,id%3為2表示分到user2表
    props:
      sql:
        show:
          true                                                  # 列印sql
           

這裡使用自動取模分片政策,

ShardingShphere

内置了如下分片算法:

  • 自動分片算法:取模分片、哈希取模分片、基于分片容量的範圍分片、基于分片邊界的範圍分片、自動時間段分片
  • 标準分片算法:行表達式分片、時間範圍分片
  • 複合行表達式分片
  • Hint

    行表達式分片

如果不能滿足需要還可以自定義分片算法,具體請看官方文檔。

5 測試代碼生成

使用

MyBaits Plus Generator

生成相應代碼,具體使用可以參考筆者之前的文章,這裡直接放上生成類的代碼:

import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;

public class MyBatisPlusGenerator {
    public static void main(String[] args) {
        DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder("jdbc:mysql://localhost:3306/test0", "root", "123456").build();
        String projectPath = System.getProperty("user.dir");
        StrategyConfig strategyConfig = new StrategyConfig.Builder().addInclude("user").build();
        GlobalConfig globalConfig = new GlobalConfig.Builder().outputDir(projectPath + "/src/main/java").openDir(false).build();
        PackageConfig packageConfig = new PackageConfig.Builder().moduleName("user").parent("com.example.demo").serviceImpl("service").build();
        new AutoGenerator(dataSourceConfig).global(globalConfig).packageInfo(packageConfig).strategy(strategyConfig).execute();
    }
}
           

UserController

類修改如下:

@RestController
@RequestMapping("/user")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class UserController {
    private final Random random = new Random();
    private final UserServiceImpl service;
    @GetMapping("/select")
    public List<User> select(){
        return service.list();
    }

    @GetMapping("/insert")
    public boolean insert(){
        return service.save(User.builder().age(random.nextInt(80)+20).name("test name").email("[email protected]").build());
    }
}
           

6 增加雪花

id

生成器

首先修改

User

類,增加一個

@Builder

注解,同時修改

id

的生成政策,使用

IdType.ASSIGN_ID

@Builder
public class User implements Serializable {
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    //...
}
           

建立

id

生成器類:

import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.github.yitter.contract.IdGeneratorOptions;
import com.github.yitter.idgen.YitIdHelper;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
public class IdGenerator implements IdentifierGenerator {
    final IdGeneratorOptions options = new IdGeneratorOptions((short) 1);

    @PostConstruct
    public void init() {
        YitIdHelper.setIdGenerator(options);
    }

    @Override
    public Long nextId(Object entity) {
        return YitIdHelper.nextId();
    }
}
           

這樣生成

id

的時候,就會自動調用

nextId()

方法,其中的

id

生成器可以根據需要進行替換,換成其他雪花

id

生成器或分布式

id

生成器。

配置的時候可以參考MyBaits Plus 自定義ID生成器文檔。

7 測試

先随機插入三條資料,重新整理三次如下頁面:

localhost:8080/test/user/insert
           
Spring Boot demo系列(十三):ShardingSphere + MyBatisPlus 分庫分表1 概述2 準備資料庫環境3 建立項目4 配置檔案5 測試代碼生成6 增加雪花id生成器7 測試8 參考源碼

可以看到執行了三次插入操作,插入的三個表分别是:

  • test0.user2

  • test0.user0

  • test0.user2

因為這裡測試的時候年齡都恰好是偶數,都插入到了

test0

表。

檢視資料:

http://localhost:8080/user/select
           
Spring Boot demo系列(十三):ShardingSphere + MyBatisPlus 分庫分表1 概述2 準備資料庫環境3 建立項目4 配置檔案5 測試代碼生成6 增加雪花id生成器7 測試8 參考源碼

日志輸出如下:

Spring Boot demo系列(十三):ShardingSphere + MyBatisPlus 分庫分表1 概述2 準備資料庫環境3 建立項目4 配置檔案5 測試代碼生成6 增加雪花id生成器7 測試8 參考源碼

表示這是對六個表查詢的結果,并将最後的結果進行聚合傳回。

8 參考源碼

Java

版:

  • Github
  • 碼雲
  • CODE.CHINA

Kotlin

版:

  • Github
  • 碼雲
  • CODE.CHINA

繼續閱讀