网上自己找了很多教程但是配合SpringBoot3都无法使用,经过实验发现只有最新版5.5.0支持SpringBoot3x现在把相关读写分离配置分享给大家
相关springboot3的包这里就不多赘述,我使用的是MybatisPlus 3.5.5
首先导入相关jar包
dependency>
groupId>org.apache.shardingspheregroupId>
artifactId>shardingsphere-jdbcartifactId>
version>5.5.0version>
exclusions>
exclusion>
groupId>org.apache.shardingspheregroupId>
artifactId>shardingsphere-test-utilartifactId>
exclusion>
exclusions>
dependency>
这里放一个完整的pom给大家看看
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.0modelVersion>
packaging>pompackaging>
groupId>com.yijun.sharding.jdbcgroupId>
artifactId>spring-boot3-sharding-jdbcartifactId>
version>0.0.1-SNAPSHOTversion>
name>spring-boot3-sharding-jdbcname>
description>Demo project for Spring Bootdescription>
properties>
java.version>17java.version>
project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
spring-boot.version>3.2.4spring-boot.version>
properties>
dependencies>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-webartifactId>
exclusions>
exclusion>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-tomcatartifactId>
exclusion>
exclusions>
dependency>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-undertowartifactId>
dependency>
dependency>
groupId>com.mysqlgroupId>
artifactId>mysql-connector-jartifactId>
dependency>
dependency>
groupId>org.projectlombokgroupId>
artifactId>lombokartifactId>
version>1.18.30version>
dependency>
dependency>
groupId>org.apache.commonsgroupId>
artifactId>commons-lang3artifactId>
version>3.13.0version>
dependency>
dependency>
groupId>jakarta.persistencegroupId>
artifactId>jakarta.persistence-apiartifactId>
dependency>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-aopartifactId>
dependency>
dependency>
groupId>org.mybatis.spring.bootgroupId>
artifactId>mybatis-spring-boot-starterartifactId>
version>3.0.3version>
dependency>
dependency>
groupId>com.baomidougroupId>
artifactId>mybatis-plus-boot-starterartifactId>
version>3.5.5version>
exclusions>
exclusion>
groupId>org.mybatisgroupId>
artifactId>mybatis-springartifactId>
exclusion>
exclusion>
artifactId>mybatisartifactId>
groupId>org.mybatisgroupId>
exclusion>
exclusions>
dependency>
dependency>
groupId>org.apache.shardingspheregroupId>
artifactId>shardingsphere-jdbcartifactId>
version>5.5.0version>
exclusions>
exclusion>
groupId>org.apache.shardingspheregroupId>
artifactId>shardingsphere-test-utilartifactId>
exclusion>
exclusions>
dependency>
dependencies>
dependencyManagement>
dependencies>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-dependenciesartifactId>
version>${spring-boot.version}version>
type>pomtype>
scope>importscope>
dependency>
dependencies>
dependencyManagement>
build>
plugins>
plugin>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
第二部对springboot的application进行修改
spring:
main:
allow-bean-definition-overriding: true
application:
name: ls-backend
datasource:
driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
url: jdbc:shardingsphere:classpath:sharding.yaml
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
server:
port: 8085
servlet:
context-path: /
encoding:
force-response: true
#Mybatis扫描
mybatis:
config-location: classpath:/mybatis-config.xml
mybatis-plus:
mapper-locations: classpath:/mapper/*Mapper.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImp
那么接下来就是重点了,然后是sharding.yaml的相关配置,因为官方的文档比较碎片化,最后进行校验和处理得出的完整文档
dataSources:
ds_1:
driverClassName: com.mysql.cj.jdbc.Driver
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
jdbcUrl:
username:
password:
ds_2:
driverClassName: com.mysql.cj.jdbc.Driver
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
jdbcUrl:
username:
password:
rules:
- !SINGLE
tables:
- "*.*"
defaultDataSource: ds_1
- !READWRITE_SPLITTING
dataSources:
readwrite_ds:
writeDataSourceName: ds_1
readDataSourceNames:
- ds_2
transactionalReadQueryStrategy: PRIMARY
loadBalancerName: random
loadBalancers:
random:
type: RANDOM
props:
sql-show: true
这里我是用一个读库一个写库处理,数据库连接自己填,打印SQL可以开启可以看到读和写走到了不同的库,至于数据分片就不多赘述,我自己也没验证,不过估计在配置文件加入分片规则就可以做到,还有rules的下的配置一定要写SINGLE这个 不然它会报找不到表的错误,还有这个配置目前只有shardingjdbc 5.4.1和5.5.0可以用,其他版本并不通用 请不要混用
这里考虑到强制走写库的情况自己根据HintManager写了一个强制主库的注解和AOP如下:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)public @interface Master {}
@Slf4j
@Component
@Aspect
public class ShardingAop {
@Around("execution(* com.yijun..service.impl.*.*(..))")
public Object master(ProceedingJoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
Object ret = null;
log.info(joinPoint.toShortString());
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
Master master = method.getAnnotation(Master.class);
HintManager hintManager = null;
try {
if (Objects.nonNull(master)) {
HintManager.clear();
hintManager = HintManager.getInstance();
hintManager.setWriteRouteOnly();
}
ret = joinPoint.proceed(args);
}catch (Exception ex){
log.error("exception error",ex);
}catch (Throwable ex2){
log.error("Throwable",ex2);
}finally {
if (Objects.nonNull(master) && Objects.nonNull(hintManager)) {
hintManager.close();
}
}
return ret;
}
}
设置这个AOP后只要在service实现类方法上加上@Master注解就可以强制走读库处理了,其他情况安正常处理