springboot整合shardingjdbc
1.引入依赖
这里是整合mybatis,都一样,shardingjdbc通过自定义的数据源来拦住你的sql语句进行改写
一定要注意druid数据源
,不能使用自动装配的,要通过shardingjdbc去实例化数据源,那个自动装配会spring去实例化,用了自动装配也可以通过启动类注解排除
@SpringBootApplication(scanBasePackages="com.xxx",exclude={DruidDataSourceAutoConfigure.class})
pom.xml
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.6</version>
</dependency>
2.编写配置文件
两个配置文件 一样的 二选一
application.properties
spring.shardingsphere.datasource.names=ds0
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.url=jdbc:mysql://127.0.0.1:3308/test_user?characterEncoding=utf8&serverTimezone=UTC&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root
spring.shardingsphere.sharding.tables.test_user.actual-data-nodes=ds0.test_user_$->{1..2}
spring.shardingsphere.sharding.tables.test_user.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.test_user.table-strategy.standard.precise-algorithm-class-name=com.jsu.lzj.config.MyTablePreciseShardingAlgorithm
spring.shardingsphere.sharding.tables.test_user.table-strategy.standard.range-algorithm-class-name=com.jsu.lzj.config.MyTableRangeShardingAlgorithm
spring.shardingsphere.sharding.tables.test_user.key-generator.column=id
spring.shardingsphere.sharding.tables.test_user.key-generator.type=SNOWFLAKE
spring.shardingsphere.props.sql.show = true
mybatis.type-aliases-package=com/jsu/lzj/entity
mybatis.mapper-locations=classpath:mapper/*.xml
application.yml
server:
port: 8080
spring:
# datasource:
# url: jdbc:mysql://localhost:3308/test_user?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
# driver-class-name: com.mysql.cj.jdbc.Driver
# username: root
# password: root
shardingsphere:
defaultDataSourceName: ds0
#配置数据源 可以配置多个 实现分库
datasource:
names: ds0
ds0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3308/test_user?characterEncoding=utf8&serverTimezone=UTC&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false
username: root
password: root
sharding:
tables:
# 配置逻辑表和真实表 test_user 逻辑表 ds0上面的数据源 test_user_1 和 test_user_2真实表
test_user:
actual-data-nodes: ds0.test_user_$->{1..2}
#主键生成策略
key-generator.column: id
#雪花算法
key-generator.type: SNOWFLAKE
#配置分片策略
table-strategy:
standard:
sharding-column: id
precise-algorithm-class-name: com.jsu.lzj.config.MyTablePreciseShardingAlgorithm
range-algorithm-class-name: com.jsu.lzj.config.MyTableRangeShardingAlgorithm
# inline:
# # 最简洁的分片方式 分片建
# sharding=column: id
# # 分片策略 id是integer的 id%2 + 1
# algorithm-expression: test_user_${id % 2 + 1}
# 打印sql语句
props:
sql:
show: true
3.自定义分片算法 (可以直接用上面的行表达式分片)
自定义精准分片算法
package com.jsu.lzj.config;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import java.util.Collection;
/**
* 精准分片策略 作用于 = in 等操作
* @author lzj
* @date 2022/3/24
*/
public class MyTablePreciseShardingAlgorithm implements PreciseShardingAlgorithm<Integer> {
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<Integer> preciseShardingValue) {
//获得分片建的id
Integer value = preciseShardingValue.getValue();
//根据分片键去取余+1分表
return "test_user_" + (value % 2 + 1) ;
}
}
自定义范围分片策略
package com.jsu.lzj.config;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;
import java.util.ArrayList;
import java.util.Collection;
/**
* 范围分片算法策略 作用于between > < >= <=
* @author lzj
* @date 2022/3/24
*/
public class MyTableRangeShardingAlgorithm implements RangeShardingAlgorithm<Integer> {
@Override
public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Integer> rangeShardingValue) {
Collection<String> result = new ArrayList<String>();
int start = 1;
int end = collection.size();
//获取最大值和最小值 没有就会抛出异常 我们捕获他就好
try{
start = rangeShardingValue.getValueRange().lowerEndpoint();
}catch(IllegalStateException e){
System.out.println("java.lang.IllegalStateException: range unbounded on this side");
}
try{
end = rangeShardingValue.getValueRange().upperEndpoint();
}catch(IllegalStateException e){
System.out.println("java.lang.IllegalStateException: range unbounded on this side");
}
for(int i=start; i <= end; i++){
//根据范围判断需要查询哪些表
//collection中包含所有真实表名 我们配置文件中的 ${1..2} 说明有两张
String tableName = "test_user_"+ ( i % 2 + 1);
if(collection.contains(tableName)){
if(result.contains(tableName)){
result.add(tableName);
}
}
}
return result;
}
}
4.总结
接下来我们就可以和平常一样写sql去查就行,当我们查询逻辑表的时候,shardingjdbc就会帮我们拦截,根据分片键决定选择哪一张实际表
如果查询条件不包含分片键就会路由到所有表进行查询,最后合并结果
当我们插入不含分片键,也没有在shardingjdbc中配置自动生成策略应该会报错
注意事项
注意那个数据源的地方
注意springboottest
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MySpringBootApplication.class)
分库分表有四种
水平分表:将同样的表格分成多个
垂直分表:将一个表格的不同属性分到多个表格里
水平分库:将同样的表格分成多个到不同数据库
垂直分库:将不同的表格分到不同的数据库,专库专用
shardingjdbc执行流程
sql解析:首先拦截你的sql,然后经过词法分析决定哪些字段需要改写
sql路由:根据分片键决定要路由到哪一些表中
sql改写:将sql逻辑表和其他需要改写的sql字段改写成真实的sql
sql执行:执行sql语句
结果合并:将返回的结果进行合并处理
参考资料:
版权声明:本文为xc979906570原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。