Springboot 集成 sharding sphere,mybatis-plus 实现分库分表

举报
小米粒-biubiubiu 发表于 2021/05/25 02:38:49 2021/05/25
【摘要】 创建spring boot 项目 1.添加依赖  <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <...

创建spring boot 项目

1.添加依赖 


  
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>mysql</groupId>
  7. <artifactId>mysql-connector-java</artifactId>
  8. <scope>runtime</scope>
  9. </dependency>
  10. <dependency>
  11. <groupId>com.baomidou</groupId>
  12. <artifactId>mybatis-plus-boot-starter</artifactId>
  13. <version>${mybatis-plus.version}</version>
  14. </dependency>
  15. <dependency>
  16. <groupId>com.baomidou</groupId>
  17. <artifactId>mybatis-plus-generator</artifactId>
  18. <version>${mybatis-plus.version}</version>
  19. </dependency>
  20. <dependency>
  21. <groupId>org.projectlombok</groupId>
  22. <artifactId>lombok</artifactId>
  23. <optional>true</optional>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter-test</artifactId>
  28. <scope>test</scope>
  29. </dependency>
  30. <dependency>
  31. <groupId>org.apache.shardingsphere</groupId>
  32. <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
  33. <version>4.0.0-RC1</version>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.apache.shardingsphere</groupId>
  37. <artifactId>sharding-jdbc-spring-namespace</artifactId>
  38. <version>4.0.0-RC1</version>
  39. </dependency>

 2.编写 application.yaml 配置文件


  
  1. server:
  2. port: 8001
  3. spring:
  4. profiles:
  5. active: master-slave
  6. application:
  7. name: exam-manage
  8. main:
  9. allow-bean-definition-overriding: true
  10. #mybatis配置
  11. mybatis-plus:
  12. mapperLocations: classpath*:mapper/*.xml
  13. typeAliasesPackage: com.dzx.ccb.exam.exammanage.entity
  14. configuration:
  15. map-underscore-to-camel-case: true
  16. cache-enabled: true
  17. logging:
  18. level:
  19. com.dzx.ccb.exam.exammanage.mapper: DEBUG

3. 编写测试接口


  
  1. package com.dzx.ccb.exam.exammanage.controller;
  2. import com.baomidou.mybatisplus.core.metadata.IPage;
  3. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  4. import com.dzx.ccb.exam.exammanage.entity.Student;
  5. import com.dzx.ccb.exam.exammanage.service.StudentService;
  6. import com.dzx.ccb.exam.exammanage.util.JsonReponse;
  7. import groovy.transform.AutoClone;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.validation.annotation.Validated;
  10. import org.springframework.web.bind.annotation.*;
  11. /**
  12. * @author DuanZhaoXu
  13. * @ClassName:
  14. * @Description:
  15. * @date 2021年05月21日 12:52:20
  16. */
  17. @RestController
  18. @RequestMapping("/student")
  19. public class StudentController {
  20. @Autowired
  21. private StudentService studentService;
  22. @PostMapping("/add")
  23. public JsonReponse<Boolean> addStudent(@RequestBody Student student) {
  24. boolean result = studentService.save(student);
  25. return JsonReponse.success(result);
  26. }
  27. @GetMapping("/getById")
  28. public JsonReponse<Student> addStudent(@RequestParam("id") Long id) {
  29. return JsonReponse.success(studentService.getById(id));
  30. }
  31. @GetMapping("/list")
  32. public JsonReponse<Student> list() {
  33. return JsonReponse.success(studentService.list());
  34. }
  35. @GetMapping("pageList")
  36. public JsonReponse<Student> pageList(@RequestParam("current") long current, @RequestParam("size") long size) {
  37. Page<Student> iPage = new Page<Student>(current, size);
  38. iPage.setDesc("id");
  39. return JsonReponse.success(studentService.page(iPage));
  40. }
  41. }

4. 简单 分库配置文件 :application-sharding-databases.yaml 配置文件

ds0和ds1两个数据库下都创建student表


  
  1. #分库配置
  2. spring:
  3. shardingsphere:
  4. datasource:
  5. names: ds0,ds1
  6. ds0:
  7. type: com.zaxxer.hikari.HikariDataSource
  8. driverClassName: com.mysql.cj.jdbc.Driver
  9. jdbc-url: jdbc:mysql://127.0.0.1:3306/ds0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  10. username: root
  11. password: 123456
  12. ds1:
  13. type: com.zaxxer.hikari.HikariDataSource
  14. driverClassName: com.mysql.cj.jdbc.Driver
  15. jdbc-url: jdbc:mysql://127.0.0.1:3306/ds1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  16. username: root
  17. password: 123456
  18. sharding:
  19. default-database-strategy:
  20. inline:
  21. sharding-column: id
  22. algorithm-expression: ds$->{id % 2}
  23. tables:
  24. student:
  25. actual-data-nodes: ds$->{0..1}.student
  26. key-generator:
  27. column: id
  28. type: SNOWFLAKE
  29. props:
  30. worker:
  31. id: 33
  32. props:
  33. sql:
  34. show: true

5. 简单分表配置: application-sharding-tables.yaml

ds2数据库中创建 student0 和 student1 表


  
  1. #不分库,只分表
  2. spring:
  3. shardingsphere:
  4. datasource:
  5. names: ds2
  6. ds2:
  7. type: com.zaxxer.hikari.HikariDataSource
  8. driverClassName: com.mysql.cj.jdbc.Driver
  9. jdbc-url: jdbc:mysql://127.0.0.1:3306/ds2?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  10. username: root
  11. password: 123456
  12. sharding:
  13. tables:
  14. student:
  15. actual-data-nodes: ds2.student$->{0..1}
  16. table-strategy:
  17. inline:
  18. sharding-column: id
  19. algorithm-expression: student$->{id % 2}
  20. key-generator:
  21. column: id
  22. type: SNOWFLAKE
  23. props:
  24. worker:
  25. id: 33
  26. props:
  27. sql:
  28. show: true

6.分库 + 分表配置 : application-sharding-databases-tables.yaml

ds0 , ds1 ,ds2 三个数据库中 分别创建 student0 和 student1 表


  
  1. # 同时分库,分表
  2. spring:
  3. shardingsphere:
  4. datasource:
  5. names: ds0,ds1,ds2
  6. ds0:
  7. type: com.zaxxer.hikari.HikariDataSource
  8. driverClassName: com.mysql.cj.jdbc.Driver
  9. jdbc-url: jdbc:mysql://127.0.0.1:3306/ds0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  10. username: root
  11. password: 123456
  12. ds1:
  13. type: com.zaxxer.hikari.HikariDataSource
  14. driverClassName: com.mysql.cj.jdbc.Driver
  15. jdbc-url: jdbc:mysql://127.0.0.1:3306/ds1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  16. username: root
  17. password: 123456
  18. ds2:
  19. type: com.zaxxer.hikari.HikariDataSource
  20. driverClassName: com.mysql.cj.jdbc.Driver
  21. jdbc-url: jdbc:mysql://127.0.0.1:3306/ds2?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  22. username: root
  23. password: 123456
  24. sharding:
  25. default-database-strategy:
  26. inline:
  27. sharding-column: id
  28. algorithm-expression: ds$->{id % 3}
  29. tables:
  30. student:
  31. actual-data-nodes: ds$->{0..2}.student$->{0..1}
  32. table-strategy:
  33. inline:
  34. sharding-column: id
  35. algorithm-expression: student$->{id % 2}
  36. key-generator:
  37. column: id
  38. type: SNOWFLAKE
  39. props:
  40. worker:
  41. id: 33
  42. props:
  43. sql:
  44. show: true

7.  简单主从数据库配置 :application-master-slave.yaml

ds0为 主库,ds1 和 ds2 为从库,数据库架构配置了主从读写分离的情况下


  
  1. #主从数据库配置
  2. spring:
  3. shardingsphere:
  4. datasource:
  5. names: ds0,ds1,ds2
  6. ds0:
  7. type: com.zaxxer.hikari.HikariDataSource
  8. driverClassName: com.mysql.cj.jdbc.Driver
  9. jdbc-url: jdbc:mysql://127.0.0.1:3306/ds0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  10. username: root
  11. password: 123456
  12. ds1:
  13. type: com.zaxxer.hikari.HikariDataSource
  14. driverClassName: com.mysql.cj.jdbc.Driver
  15. jdbc-url: jdbc:mysql://127.0.0.1:3306/ds1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  16. username: root
  17. password: 123456
  18. ds2:
  19. type: com.zaxxer.hikari.HikariDataSource
  20. driverClassName: com.mysql.cj.jdbc.Driver
  21. jdbc-url: jdbc:mysql://127.0.0.1:3306/ds2?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  22. username: root
  23. password: 123456
  24. masterslave:
  25. load-balance-algorithm-type: random
  26. name: student_ms
  27. master-data-source-name: ds0
  28. slave-data-source-names: ds1,ds2
  29. props:
  30. sql:
  31. show: true

8. 主从数据库+ 分库分表配置:application-sharding-master-slave.yaml

两主 + 四从

主库 dsmaster0  ->  从库 dsmaster0-slave0, dsmaster0-slave1

主库 dsmaster1  ->  从库 dsmaster1-slave0, dsmaster1-slave1


  
  1. spring:
  2. shardingsphere:
  3. datasource:
  4. names: dsmaster0,dsmaster1,dsmaster0-slave0,dsmaster0-slave1,dsmaster1-slave0,dsmaster1-slave1
  5. dsmaster0:
  6. type: com.zaxxer.hikari.HikariDataSource
  7. driverClassName: com.mysql.cj.jdbc.Driver
  8. jdbc-url: jdbc:mysql://127.0.0.1:3306/dsmaster0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  9. username: root
  10. password: 123456
  11. dsmaster0-slave0:
  12. type: com.zaxxer.hikari.HikariDataSource
  13. driverClassName: com.mysql.cj.jdbc.Driver
  14. jdbc-url: jdbc:mysql://127.0.0.1:3306/dsmaster0-slave0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  15. username: root
  16. password: 123456
  17. dsmaster0-slave1:
  18. type: com.zaxxer.hikari.HikariDataSource
  19. driverClassName: com.mysql.cj.jdbc.Driver
  20. jdbc-url: jdbc:mysql://127.0.0.1:3306/dsmaster0-slave1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  21. username: root
  22. password: 123456
  23. dsmaster1:
  24. type: com.zaxxer.hikari.HikariDataSource
  25. driverClassName: com.mysql.cj.jdbc.Driver
  26. jdbc-url: jdbc:mysql://127.0.0.1:3306/dsmaster1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  27. username: root
  28. password: 123456
  29. dsmaster1-slave0:
  30. type: com.zaxxer.hikari.HikariDataSource
  31. driverClassName: com.mysql.cj.jdbc.Driver
  32. jdbc-url: jdbc:mysql://127.0.0.1:3306/dsmaster1-slave0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  33. username: root
  34. password: 123456
  35. dsmaster1-slave1:
  36. type: com.zaxxer.hikari.HikariDataSource
  37. driverClassName: com.mysql.cj.jdbc.Driver
  38. jdbc-url: jdbc:mysql://127.0.0.1:3306/dsmaster1-slave1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  39. username: root
  40. password: 123456
  41. sharding:
  42. default-database-strategy:
  43. inline:
  44. sharding-column: id
  45. algorithm-expression: dsmaster$->{id % 2}
  46. tables:
  47. student:
  48. actual-data-nodes: dsmaster$->{0..1}.student$->{0..1}
  49. table-strategy:
  50. inline:
  51. sharding-column: id
  52. algorithm-expression: student$->{id % 2}
  53. key-generator:
  54. column: id
  55. type: SNOWFLAKE
  56. props:
  57. worker:
  58. id: 33
  59. master-slave-rules:
  60. dsmaster0:
  61. master-data-source-name: dsmaster0
  62. slave-data-source-names: dsmaster0-slave0, dsmaster0-slave1
  63. dsmaster1:
  64. master-data-source-name: dsmaster1
  65. slave-data-source-names: dsmaster1-slave0, dsmaster1-slave1

另外可以使用绑定表和广播表配置项进行性能调优

spring.shardingsphere.sharding.binding-tables

spring.shardingsphere.sharding.broadcast-tables

设置绑定表和广播表

接下来我们需要设置绑定表。绑定表(BindingTable)是 ShardingSphere 中提出的一个新概念,我来给你解释一下。

所谓绑定表,是指与分片规则一致的一组主表和子表。例如,在我们的业务场景中,health_record 表和 health_task 表中都存在一个 record_id 字段。如果我们在应用过程中按照这个 record_id 字段进行分片,那么这两张表就可以构成互为绑定表关系。

引入绑定表概念的根本原因在于,互为绑定表关系的多表关联查询不会出现笛卡尔积,因此关联查询效率将大大提升。举例说明,如果所执行的为下面这条 SQL:

SELECT record.remark_name FROM health_record record JOIN health_task task ON record.record_id=task.record_id WHERE record.record_id in (1, 2);

 

如果我们不显式配置绑定表关系,假设分片键 record_id 将值 1 路由至第 1 片,将数值 2 路由至第 0 片,那么路由后的 SQL 应该为 4 条,它们呈现为笛卡尔积:


  
  1. SELECT record.remark_name FROM health_record0 record JOIN health_task0 task ON record.record_id=task.record_id WHERE record.record_id in (1, 2);
  2.  
  3. SELECT record.remark_name FROM health_record0 record JOIN health_task1 task ON record.record_id=task.record_id WHERE record.record_id in (1, 2);
  4.  
  5. SELECT record.remark_name FROM health_record1 record JOIN health_task0 task ON record.record_id=task.record_id WHERE record.record_id in (1, 2);
  6.  
  7. SELECT record.remark_name FROM health_record1 record JOIN health_task1 task ON record.record_id=task.record_id WHERE record.record_id in (1, 2);


然后,在配置绑定表关系后,路由的 SQL 就会减少到 2 条:


  
  1. SELECT record.remark_name FROM health_record0 record JOIN health_task0 task ON record.record_id=task.record_id WHERE record.record_id in (1, 2);
  2.  
  3. SELECT record.remark_name FROM health_record1 record JOIN health_task1 task ON record.record_id=task.record_id WHERE record.record_id in (1, 2);


请注意,如果想要达到这种效果,互为绑定表的各个表的分片键要完全相同。在上面的这些 SQL 语句中,我们不难看出,这个需要完全相同的分片键就是 record_id。

让我们回到案例中的场景,显然,health_record 和 health_task 应该互为绑定表关系。所以,我们可以在配置文件中添加对这种关系的配置:

spring.shardingsphere.sharding.binding-tables=health_record, health_task
 


介绍完绑定表,再来看广播表的概念。所谓广播表(BroadCastTable),是指所有分片数据源中都存在的表,也就是说,这种表的表结构和表中的数据在每个数据库中都是完全一样的。广播表的适用场景比较明确,通常针对数据量不大且需要与海量数据表进行关联查询的应用场景,典型的例子就是每个分片数据库中都应该存在的字典表。

同样回到我们的场景,对于 health_level 表而言,由于它保存着有限的健康等级信息,可以认为它就是这样的一种字典表。所以,我们也在配置文件中添加了对广播表的定义,在下面这段代码中你可以看到:

spring.shardingsphere.sharding.broadcast-tables=health_level
 

 

 

文章来源: blog.csdn.net,作者:血煞风雨城2018,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/qq_31905135/article/details/117127914

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。