网上的基于配置文件的文章太多了且有些写的乱七八糟对新手极为不友好,本篇文章采用 全部 Java 编码的方式,来实现数据的分库分表,并力求做到简单明了
工具准备
- 安装Spring boot,我这里是通过idea安装, java8,maven
- 这里采用mybatis逆向工程生成代码,生成插件选择Maven
- 连接池采用阿里巴巴的Druid
安装依赖
pom文件如下,主要依赖有,mybatis-spring-boot-starter,druid-spring-boot-starter,sharding-jdbc-core
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description>
<properties> <java.version>1.8</java.version> </properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.16</version> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.6</version> </dependency>
<!-- https://mvnrepository.com/artifact/org.apache.shardingsphere/sharding-jdbc-core --> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-core</artifactId> <version>4.0.1</version> </dependency>
</dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin>
<plugin> <groupId>org.mybatis.generator</groupId> <configuration> <overwrite>true</overwrite> </configuration> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.4.0</version> </plugin> </plugins> </build>
</project>
|
生成Model
具体教程在这篇文章有详细讲解 https://blog.csdn.net/qq_28163609/article/details/108235740
注意:记得最后在Mapper文件上加上@Mapper注解
配置数据源和定义分库分表策略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| package com.example.demo.config;
import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration; import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration; import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration; import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration; import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm; import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue; import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource; import java.sql.SQLException; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Properties;
@Configuration public class DataSourceConfig {
@Bean public DataSource getDataSource() throws SQLException { ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration(); shardingRuleConfig.getTableRuleConfigs().add(getStudentTableRuleConfiguration()); shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("user_id", "test${user_id % 2}")); shardingRuleConfig.setDefaultTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("user_id", new ModuloShardingTableAlgorithm())); return ShardingDataSourceFactory.createDataSource(createDataSourceMap(), shardingRuleConfig, new Properties()); }
TableRuleConfiguration getStudentTableRuleConfiguration() { return new TableRuleConfiguration("student", "test${0..1}.student${0..3}"); }
static class ModuloShardingTableAlgorithm implements PreciseShardingAlgorithm<Integer>{ @Override public String doSharding(Collection<String> collection, PreciseShardingValue<Integer> preciseShardingValue) { System.out.println(preciseShardingValue.getValue()); return "student_0"+preciseShardingValue.getValue() % 3; } }
private DataSource getDruidDataSource0(){ DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUsername("root"); dataSource.setPassword(""); dataSource.setUrl("jdbc:mysql://localhost:3306/test0?useSSL=false"); return dataSource; }
private DataSource getDruidDataSource1(){ DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUsername("root"); dataSource.setPassword(""); dataSource.setUrl("jdbc:mysql://localhost:3306/test1?useSSL=false"); return dataSource; }
Map<String, DataSource> createDataSourceMap() { Map<String, DataSource> result = new HashMap<>(); result.put("test0", getDruidDataSource0()); result.put("test1", getDruidDataSource1()); return result; }
}
|
代码逻辑已经详细写了注释
插入数据测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package com.example.demo.controller;
import com.example.demo.mapper.StudentMapper; import com.example.demo.model.Student; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
@RestController public class TestController {
@Autowired StudentMapper studentMapper;
@RequestMapping("/insert") public String insert(){
for(int i = 1; i <= 100; i++){ Student student = new Student(); student.setName("占三"); student.setUserId(i); studentMapper.insert(student); } return "success"; } }
|
效果:test0库的student_00表, 譬如user_id 为6 的对2(数据库的数量)取模为0,对3(表的数量)取模为0
student_01的数据如下:和预想中一样
至此完成,分库分表,利用Sharding-jdbc分库分表还是很容易实现的,且对代码的侵入性较小。
数据库结构为,建立两个数据库名字为test0,test1
以下是表结构,分别在两个数据库中执行即可
CREATE TABLE student_01
(
id
int(11) NOT NULL AUTO_INCREMENT,
name
varchar(255) NOT NULL DEFAULT ‘’,
user_id
int(11) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
CREATE TABLE student_02
(
id
int(11) NOT NULL AUTO_INCREMENT,
name
varchar(255) NOT NULL DEFAULT ‘’,
user_id
int(11) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
CREATE TABLE student_03
(
id
int(11) NOT NULL AUTO_INCREMENT,
name
varchar(255) NOT NULL DEFAULT ‘’,
user_id
int(11) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;