经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring Boot » 查看文章
SpringBoot 2.0 整合sharding-jdbc中间件,实现数据分库分表
来源:cnblogs  作者:知了一笑  时间:2019/6/4 15:54:15  对本文有异议

一、水平分割

1、水平分库
1)、概念:
以字段为依据,按照一定策略,将一个库中的数据拆分到多个库中。
2)、结果
每个库的结构都一样;数据都不一样;
所有库的并集是全量数据;
2、水平分表
1)、概念
以字段为依据,按照一定策略,将一个表中的数据拆分到多个表中。
2)、结果
每个表的结构都一样;数据都不一样;
所有表的并集是全量数据;

二、Shard-jdbc 中间件

1、架构图

2、特点
1)、Sharding-JDBC直接封装JDBC API,旧代码迁移成本几乎为零。
2)、适用于任何基于Java的ORM框架,如Hibernate、Mybatis等 。
3)、可基于任何第三方的数据库连接池,如DBCP、C3P0、 BoneCP、Druid等。
4)、以jar包形式提供服务,无proxy代理层,无需额外部署,无其他依赖。
5)、分片策略灵活,可支持等号、between、in等多维度分片,也可支持多分片键。
6)、SQL解析功能完善,支持聚合、分组、排序、limit、or等查询。

三、项目演示

1、项目结构

  1. springboot 2.0 版本
  2. druid 1.1.13 版本
  3. sharding-jdbc 3.1 版本

2、数据库配置


  1. 一台基础库映射(shard_one
  2. 两台库做分库分表(shard_twoshard_three)。
  3. 表使用:table_onetable_two

3、核心代码块

数据源配置文件

  1. spring:
  2. datasource:
  3. # 数据源:shard_one
  4. dataOne:
  5. type: com.alibaba.druid.pool.DruidDataSource
  6. druid:
  7. driverClassName: com.mysql.jdbc.Driver
  8. url: jdbc:mysql://localhost:3306/shard_one?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&useSSL=false
  9. username: root
  10. password: 123
  11. initial-size: 10
  12. max-active: 100
  13. min-idle: 10
  14. max-wait: 60000
  15. pool-prepared-statements: true
  16. max-pool-prepared-statement-per-connection-size: 20
  17. time-between-eviction-runs-millis: 60000
  18. min-evictable-idle-time-millis: 300000
  19. max-evictable-idle-time-millis: 60000
  20. validation-query: SELECT 1 FROM DUAL
  21. # validation-query-timeout: 5000
  22. test-on-borrow: false
  23. test-on-return: false
  24. test-while-idle: true
  25. connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
  26. # 数据源:shard_two
  27. dataTwo:
  28. type: com.alibaba.druid.pool.DruidDataSource
  29. druid:
  30. driverClassName: com.mysql.jdbc.Driver
  31. url: jdbc:mysql://localhost:3306/shard_two?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&useSSL=false
  32. username: root
  33. password: 123
  34. initial-size: 10
  35. max-active: 100
  36. min-idle: 10
  37. max-wait: 60000
  38. pool-prepared-statements: true
  39. max-pool-prepared-statement-per-connection-size: 20
  40. time-between-eviction-runs-millis: 60000
  41. min-evictable-idle-time-millis: 300000
  42. max-evictable-idle-time-millis: 60000
  43. validation-query: SELECT 1 FROM DUAL
  44. # validation-query-timeout: 5000
  45. test-on-borrow: false
  46. test-on-return: false
  47. test-while-idle: true
  48. connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
  49. # 数据源:shard_three
  50. dataThree:
  51. type: com.alibaba.druid.pool.DruidDataSource
  52. druid:
  53. driverClassName: com.mysql.jdbc.Driver
  54. url: jdbc:mysql://localhost:3306/shard_three?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&useSSL=false
  55. username: root
  56. password: 123
  57. initial-size: 10
  58. max-active: 100
  59. min-idle: 10
  60. max-wait: 60000
  61. pool-prepared-statements: true
  62. max-pool-prepared-statement-per-connection-size: 20
  63. time-between-eviction-runs-millis: 60000
  64. min-evictable-idle-time-millis: 300000
  65. max-evictable-idle-time-millis: 60000
  66. validation-query: SELECT 1 FROM DUAL
  67. # validation-query-timeout: 5000
  68. test-on-borrow: false
  69. test-on-return: false
  70. test-while-idle: true
  71. connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

数据库分库策略

  1. /**
  2. * 数据库映射计算
  3. */
  4. public class DataSourceAlg implements PreciseShardingAlgorithm<String> {
  5. private static Logger LOG = LoggerFactory.getLogger(DataSourceAlg.class);
  6. @Override
  7. public String doSharding(Collection<String> names, PreciseShardingValue<String> value) {
  8. LOG.debug("分库算法参数 {},{}",names,value);
  9. int hash = HashUtil.rsHash(String.valueOf(value.getValue()));
  10. return "ds_" + ((hash % 2) + 2) ;
  11. }
  12. }

数据表1分表策略

  1. /**
  2. * 分表算法
  3. */
  4. public class TableOneAlg implements PreciseShardingAlgorithm<String> {
  5. private static Logger LOG = LoggerFactory.getLogger(TableOneAlg.class);
  6. /**
  7. * 该表每个库分5张表
  8. */
  9. @Override
  10. public String doSharding(Collection<String> names, PreciseShardingValue<String> value) {
  11. LOG.debug("分表算法参数 {},{}",names,value);
  12. int hash = HashUtil.rsHash(String.valueOf(value.getValue()));
  13. return "table_one_" + (hash % 5+1);
  14. }
  15. }

数据表2分表策略

  1. /**
  2. * 分表算法
  3. */
  4. public class TableTwoAlg implements PreciseShardingAlgorithm<String> {
  5. private static Logger LOG = LoggerFactory.getLogger(TableTwoAlg.class);
  6. /**
  7. * 该表每个库分5张表
  8. */
  9. @Override
  10. public String doSharding(Collection<String> names, PreciseShardingValue<String> value) {
  11. LOG.debug("分表算法参数 {},{}",names,value);
  12. int hash = HashUtil.rsHash(String.valueOf(value.getValue()));
  13. return "table_two_" + (hash % 5+1);
  14. }
  15. }

数据源集成配置

  1. /**
  2. * 数据库分库分表配置
  3. */
  4. @Configuration
  5. public class ShardJdbcConfig {
  6. // 省略了 druid 配置,源码中有
  7. /**
  8. * Shard-JDBC 分库配置
  9. */
  10. @Bean
  11. public DataSource dataSource (@Autowired DruidDataSource dataOneSource,
  12. @Autowired DruidDataSource dataTwoSource,
  13. @Autowired DruidDataSource dataThreeSource) throws Exception {
  14. ShardingRuleConfiguration shardJdbcConfig = new ShardingRuleConfiguration();
  15. shardJdbcConfig.getTableRuleConfigs().add(getTableRule01());
  16. shardJdbcConfig.getTableRuleConfigs().add(getTableRule02());
  17. shardJdbcConfig.setDefaultDataSourceName("ds_0");
  18. Map<String,DataSource> dataMap = new LinkedHashMap<>() ;
  19. dataMap.put("ds_0",dataOneSource) ;
  20. dataMap.put("ds_2",dataTwoSource) ;
  21. dataMap.put("ds_3",dataThreeSource) ;
  22. Properties prop = new Properties();
  23. return ShardingDataSourceFactory.createDataSource(dataMap, shardJdbcConfig, new HashMap<>(), prop);
  24. }
  25. /**
  26. * Shard-JDBC 分表配置
  27. */
  28. private static TableRuleConfiguration getTableRule01() {
  29. TableRuleConfiguration result = new TableRuleConfiguration();
  30. result.setLogicTable("table_one");
  31. result.setActualDataNodes("ds_${2..3}.table_one_${1..5}");
  32. result.setDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("phone", new DataSourceAlg()));
  33. result.setTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("phone", new TableOneAlg()));
  34. return result;
  35. }
  36. private static TableRuleConfiguration getTableRule02() {
  37. TableRuleConfiguration result = new TableRuleConfiguration();
  38. result.setLogicTable("table_two");
  39. result.setActualDataNodes("ds_${2..3}.table_two_${1..5}");
  40. result.setDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("phone", new DataSourceAlg()));
  41. result.setTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("phone", new TableTwoAlg()));
  42. return result;
  43. }
  44. }

测试代码执行流程

  1. @RestController
  2. public class ShardController {
  3. @Resource
  4. private ShardService shardService ;
  5. /**
  6. * 1、建表流程
  7. */
  8. @RequestMapping("/createTable")
  9. public String createTable (){
  10. shardService.createTable();
  11. return "success" ;
  12. }
  13. /**
  14. * 2、生成表 table_one 数据
  15. */
  16. @RequestMapping("/insertOne")
  17. public String insertOne (){
  18. shardService.insertOne();
  19. return "SUCCESS" ;
  20. }
  21. /**
  22. * 3、生成表 table_two 数据
  23. */
  24. @RequestMapping("/insertTwo")
  25. public String insertTwo (){
  26. shardService.insertTwo();
  27. return "SUCCESS" ;
  28. }
  29. /**
  30. * 4、查询表 table_one 数据
  31. */
  32. @RequestMapping("/selectOneByPhone/{phone}")
  33. public TableOne selectOneByPhone (@PathVariable("phone") String phone){
  34. return shardService.selectOneByPhone(phone);
  35. }
  36. /**
  37. * 5、查询表 table_one 数据
  38. */
  39. @RequestMapping("/selectTwoByPhone/{phone}")
  40. public TableTwo selectTwoByPhone (@PathVariable("phone") String phone){
  41. return shardService.selectTwoByPhone(phone);
  42. }
  43. }

四、项目源码

  1. GitHub:知了一笑
  2. https://github.com/cicadasmile/middle-ware-parent

原文链接:http://www.cnblogs.com/cicada-smile/p/10970626.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号