You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 9.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. # spring-boot-demo-sharding-jdbc
  2. > 本 demo 主要演示了如何集成 `sharding-jdbc` 实现分库分表操作,ORM 层使用了`Mybatis-Plus`简化开发,童鞋们可以按照自己的喜好替换为 JPA、通用Mapper、JdbcTemplate甚至原生的JDBC都可以。
  3. >
  4. > PS:
  5. >
  6. > 1. 目前当当官方提供的starter存在bug,版本号:`3.1.0`,因此本demo采用手动配置。
  7. > 2. 文档真的很垃圾​ :joy:
  8. ## 1. 运行方式
  9. 1. 在数据库创建2个数据库,分别为:`spring-boot-demo`、`spring-boot-demo-2`
  10. 2. 去数据库执行 `sql/schema.sql` ,创建 `6` 张分片表
  11. 3. 找到 `DataSourceShardingConfig` 配置类,修改 `数据源` 的相关配置,位于 `dataSourceMap()` 这个方法
  12. 4. 找到测试类 `SpringBootDemoShardingJdbcApplicationTests` 进行测试
  13. ## 2. 关键代码
  14. ### 2.1. `pom.xml`
  15. ```xml
  16. <?xml version="1.0" encoding="UTF-8"?>
  17. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  18. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  19. <modelVersion>4.0.0</modelVersion>
  20. <artifactId>spring-boot-demo-sharding-jdbc</artifactId>
  21. <version>1.0.0-SNAPSHOT</version>
  22. <packaging>jar</packaging>
  23. <name>spring-boot-demo-sharding-jdbc</name>
  24. <description>Demo project for Spring Boot</description>
  25. <parent>
  26. <groupId>com.xkcoding</groupId>
  27. <artifactId>spring-boot-demo</artifactId>
  28. <version>1.0.0-SNAPSHOT</version>
  29. </parent>
  30. <properties>
  31. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  32. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  33. <java.version>1.8</java.version>
  34. </properties>
  35. <dependencies>
  36. <dependency>
  37. <groupId>org.springframework.boot</groupId>
  38. <artifactId>spring-boot-starter</artifactId>
  39. </dependency>
  40. <dependency>
  41. <groupId>org.springframework.boot</groupId>
  42. <artifactId>spring-boot-starter-test</artifactId>
  43. <scope>test</scope>
  44. </dependency>
  45. <dependency>
  46. <groupId>com.baomidou</groupId>
  47. <artifactId>mybatis-plus-boot-starter</artifactId>
  48. <version>3.1.0</version>
  49. </dependency>
  50. <dependency>
  51. <groupId>mysql</groupId>
  52. <artifactId>mysql-connector-java</artifactId>
  53. </dependency>
  54. <dependency>
  55. <groupId>io.shardingsphere</groupId>
  56. <artifactId>sharding-jdbc-core</artifactId>
  57. <version>3.1.0</version>
  58. </dependency>
  59. <dependency>
  60. <groupId>cn.hutool</groupId>
  61. <artifactId>hutool-all</artifactId>
  62. </dependency>
  63. <dependency>
  64. <groupId>org.projectlombok</groupId>
  65. <artifactId>lombok</artifactId>
  66. <optional>true</optional>
  67. </dependency>
  68. </dependencies>
  69. <build>
  70. <finalName>spring-boot-demo-sharding-jdbc</finalName>
  71. <plugins>
  72. <plugin>
  73. <groupId>org.springframework.boot</groupId>
  74. <artifactId>spring-boot-maven-plugin</artifactId>
  75. </plugin>
  76. </plugins>
  77. </build>
  78. </project>
  79. ```
  80. ### 2.2. `CustomSnowflakeKeyGenerator.java`
  81. ```java
  82. package com.xkcoding.sharding.jdbc.config;
  83. import cn.hutool.core.lang.Snowflake;
  84. import io.shardingsphere.core.keygen.KeyGenerator;
  85. /**
  86. * <p>
  87. * 自定义雪花算法,替换 DefaultKeyGenerator,避免DefaultKeyGenerator生成的id大几率是偶数
  88. * </p>
  89. *
  90. * @package: com.xkcoding.sharding.jdbc.config
  91. * @description: 自定义雪花算法,替换 DefaultKeyGenerator,避免DefaultKeyGenerator生成的id大几率是偶数
  92. * @author: yangkai.shen
  93. * @date: Created in 2019-03-26 17:07
  94. * @copyright: Copyright (c) 2019
  95. * @version: V1.0
  96. * @modified: yangkai.shen
  97. */
  98. public class CustomSnowflakeKeyGenerator implements KeyGenerator {
  99. private Snowflake snowflake;
  100. public CustomSnowflakeKeyGenerator(Snowflake snowflake) {
  101. this.snowflake = snowflake;
  102. }
  103. @Override
  104. public Number generateKey() {
  105. return snowflake.nextId();
  106. }
  107. }
  108. ```
  109. ### 2.3. `DataSourceShardingConfig.java`
  110. ```java
  111. /**
  112. * <p>
  113. * sharding-jdbc 的数据源配置
  114. * </p>
  115. *
  116. * @package: com.xkcoding.sharding.jdbc.config
  117. * @description: sharding-jdbc 的数据源配置
  118. * @author: yangkai.shen
  119. * @date: Created in 2019-03-26 16:47
  120. * @copyright: Copyright (c) 2019
  121. * @version: V1.0
  122. * @modified: yangkai.shen
  123. */
  124. @Configuration
  125. public class DataSourceShardingConfig {
  126. private static final Snowflake snowflake = IdUtil.createSnowflake(1, 1);
  127. /**
  128. * 需要手动配置事务管理器
  129. */
  130. @Bean
  131. public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
  132. return new DataSourceTransactionManager(dataSource);
  133. }
  134. @Bean(name = "dataSource")
  135. @Primary
  136. public DataSource dataSource() throws SQLException {
  137. ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
  138. // 设置分库策略
  139. shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("user_id", "ds${user_id % 2}"));
  140. // 设置规则适配的表
  141. shardingRuleConfig.getBindingTableGroups().add("t_order");
  142. // 设置分表策略
  143. shardingRuleConfig.getTableRuleConfigs().add(orderTableRule());
  144. shardingRuleConfig.setDefaultDataSourceName("ds0");
  145. shardingRuleConfig.setDefaultTableShardingStrategyConfig(new NoneShardingStrategyConfiguration());
  146. Properties properties = new Properties();
  147. properties.setProperty("sql.show", "true");
  148. return ShardingDataSourceFactory.createDataSource(dataSourceMap(), shardingRuleConfig, new ConcurrentHashMap<>(16), properties);
  149. }
  150. private TableRuleConfiguration orderTableRule() {
  151. TableRuleConfiguration tableRule = new TableRuleConfiguration();
  152. // 设置逻辑表名
  153. tableRule.setLogicTable("t_order");
  154. // ds${0..1}.t_order_${0..2} 也可以写成 ds$->{0..1}.t_order_$->{0..1}
  155. tableRule.setActualDataNodes("ds${0..1}.t_order_${0..2}");
  156. tableRule.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "t_order_$->{order_id % 3}"));
  157. tableRule.setKeyGenerator(customKeyGenerator());
  158. tableRule.setKeyGeneratorColumnName("order_id");
  159. return tableRule;
  160. }
  161. private Map<String, DataSource> dataSourceMap() {
  162. Map<String, DataSource> dataSourceMap = new HashMap<>(16);
  163. // 配置第一个数据源
  164. HikariDataSource ds0 = new HikariDataSource();
  165. ds0.setDriverClassName("com.mysql.cj.jdbc.Driver");
  166. ds0.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/spring-boot-demo?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8");
  167. ds0.setUsername("root");
  168. ds0.setPassword("root");
  169. // 配置第二个数据源
  170. HikariDataSource ds1 = new HikariDataSource();
  171. ds1.setDriverClassName("com.mysql.cj.jdbc.Driver");
  172. ds1.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/spring-boot-demo-2?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8");
  173. ds1.setUsername("root");
  174. ds1.setPassword("root");
  175. dataSourceMap.put("ds0", ds0);
  176. dataSourceMap.put("ds1", ds1);
  177. return dataSourceMap;
  178. }
  179. /**
  180. * 自定义主键生成器
  181. */
  182. private KeyGenerator customKeyGenerator() {
  183. return new CustomSnowflakeKeyGenerator(snowflake);
  184. }
  185. }
  186. ```
  187. ### 2.3. `SpringBootDemoShardingJdbcApplicationTests.java`
  188. ```java
  189. /**
  190. * <p>
  191. * 测试sharding-jdbc分库分表
  192. * </p>
  193. *
  194. * @package: com.xkcoding.sharding.jdbc
  195. * @description: 测试sharding-jdbc分库分表
  196. * @author: yangkai.shen
  197. * @date: Created in 2019-03-26 13:44
  198. * @copyright: Copyright (c) 2019
  199. * @version: V1.0
  200. * @modified: yangkai.shen
  201. */
  202. @Slf4j
  203. @RunWith(SpringRunner.class)
  204. @SpringBootTest
  205. public class SpringBootDemoShardingJdbcApplicationTests {
  206. @Autowired
  207. private OrderMapper orderMapper;
  208. /**
  209. * 测试新增
  210. */
  211. @Test
  212. public void testInsert() {
  213. for (long i = 1; i < 10; i++) {
  214. for (long j = 1; j < 20; j++) {
  215. Order order = Order.builder().userId(i).orderId(j).remark(RandomUtil.randomString(20)).build();
  216. orderMapper.insert(order);
  217. }
  218. }
  219. }
  220. /**
  221. * 测试更新
  222. */
  223. @Test
  224. public void testUpdate() {
  225. Order update = new Order();
  226. update.setRemark("修改备注信息");
  227. orderMapper.update(update, Wrappers.<Order>update().lambda().eq(Order::getOrderId, 2).eq(Order::getUserId, 2));
  228. }
  229. /**
  230. * 测试删除
  231. */
  232. @Test
  233. public void testDelete() {
  234. orderMapper.delete(new QueryWrapper<>());
  235. }
  236. /**
  237. * 测试查询
  238. */
  239. @Test
  240. public void testSelect() {
  241. List<Order> orders = orderMapper.selectList(Wrappers.<Order>query().lambda().in(Order::getOrderId, 1, 2));
  242. log.info("【orders】= {}", JSONUtil.toJsonStr(orders));
  243. }
  244. }
  245. ```
  246. ## 3. 参考
  247. 1. `ShardingSphere` 官网:https://shardingsphere.apache.org/index_zh.html (虽然文档确实垃圾,但是还是得参考啊~)
  248. 2. `Mybatis-Plus` 语法参考官网:https://mybatis.plus/

一个用来深度学习并实战 spring boot 的项目,目前总共包含 66 个集成demo,已经完成 55 个。