之前写过一篇sharding-jdbc的文章,实际是简单介绍,配置部分就是线上项目使用,未能摘出来成文件,这次整理成代码,大家可以在工作上使用。
shardingjdbc的作用:在客户端对jdbc进行增强和改写,实现了分库分表
整体流程
create database db1;
CREATE TABLE `user` (
`id` bigint NOT NULL COMMENT '主键ID',
`name` varchar(30) DEFAULT NULL COMMENT '姓名',
`age` int DEFAULT NULL COMMENT '年龄',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
create database db2;
CREATE TABLE `user` (
`id` bigint NOT NULL COMMENT '主键ID',
`name` varchar(30) DEFAULT NULL COMMENT '姓名',
`age` int DEFAULT NULL COMMENT '年龄',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
use db1;
insert user(id,name,age)values(1,'sank',30);
use db2;
insert user(id,name,age)values(2,'tom',13);
项目配置
spring.application.name=ksharding-rw
server.port=7312
spring.shardingsphere.datasource.names=master,slave1
spring.shardingsphere.datasource.master.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.master.jdbc-url=jdbc:mysql://127.0.0.1:3306/db1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=123456
spring.shardingsphere.datasource.master.pool-name=HikariPool-1
spring.shardingsphere.datasource.master.minimum-idle=1
spring.shardingsphere.datasource.master.maximum-pool-size=5
spring.shardingsphere.datasource.master.idle-timeout=600000
spring.shardingsphere.datasource.master.max-lifetime=1200000
spring.shardingsphere.datasource.master.connection-timeout=30000
spring.shardingsphere.datasource.master.connection-test-query=SELECT 1
spring.shardingsphere.datasource.slave1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.slave1.jdbc-url=jdbc:mysql://127.0.0.1:3306/db2?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.slave1.username=root
spring.shardingsphere.datasource.slave1.password=123456
spring.shardingsphere.datasource.slave1.pool-name=HikariPool-2
spring.shardingsphere.datasource.slave1.minimum-idle=1
spring.shardingsphere.datasource.slave1.maximum-pool-size=5
spring.shardingsphere.datasource.slave1.idle-timeout=600000
spring.shardingsphere.datasource.slave1.max-lifetime=1200000
spring.shardingsphere.datasource.slave1.connection-timeout=30000
spring.shardingsphere.datasource.slave1.connection-test-query=SELECT 1
spring.shardingsphere.masterslave.load-balance-algorithm-type=round\_robin
spring.shardingsphere.sharding.master-slave-rules.master.master-data-source-name=master
spring.shardingsphere.sharding.master-slave-rules.master.slave-data-source-names=slave1
logging.level.org.apache.ibatis=debug
logging.level.com.mysql.cj = debug
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis.type-aliases-package=cn.beckbi.model
mybatis.mapper-locations=classpath:/mapper/\*.xml
mybatis.configuration.mapUnderscoreToCamelCase = true
management.health.db.enabled=false
mybatis配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.beckbi.dao.UserMapper">
<select id="getUserById" parameterType="long" resultType="cn.beckbi.model.User">
select * from user where id = #{id}
</select>
</mapper>
大家按照我的这个样式去写
###方案一
public User getByIdFromMaster(Long id) {
return Optional.ofNullable(id).map(uid -> {
User user = null;
HintManager.clear();
try (HintManager hintManager = HintManager.getInstance()) {
hintManager.setMasterRouteOnly();
user = userMapper.getUserById(uid);
}
return user;
}).orElse(null);
}
@ShardingJdbcMaster
@Override
public User getByIdFromMaster2(Long id) {
return userMapper.getUserById(id);
}
定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface ShardingJdbcMaster {
}
定义aop
@Slf4j
@Component
@Aspect
public class ShardingAop {
@Around("execution(* cn.beckbi.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();
ShardingJdbcMaster shardingJdbcMaster = method.getAnnotation(ShardingJdbcMaster.class);
HintManager hintManager = null;
try {
if (Objects.nonNull(shardingJdbcMaster)) {
HintManager.clear();
hintManager = HintManager.getInstance();
hintManager.setMasterRouteOnly();
}
ret = joinPoint.proceed(args);
}catch (Exception ex){
log.error("exception error",ex);
}catch (Throwable ex2){
log.error("Throwable",ex2);
}finally {
if (Objects.nonNull(shardingJdbcMaster) && Objects.nonNull(hintManager)) {
hintManager.close();
}
}
return ret;
}
}
验证
项目代码:https://github.com/beckbikang/spring-cloud/tree/main/ksharding/ksharding-rw
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。