目录
1.项目搭建好后先添加配置文件
spring:
druid:
datasource:
master:
username: root
password: 123456
jdbc-url: jdbc:mysql://10.0.2.1:3306/test1?useSSL=false&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
slave:
username: root
password: 123456
jdbc-url: jdbc:mysql://10.0.2.1:3306/test2?useSSL=false&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
logging:
level:
com.jhy.mapper: debug # 控制台输出sql语句
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.jhy.pojo
configuration:
map-underscore-to-camel-case: true #开启驼峰式命名
2.自定义数据源
首先先根据配置文件定义的数据源生成两个数据源对象
然后使用AbstractRoutingDataSource生成动态数据源
@Slf4j
@Configuration
public class MyDataSourceConfiguration {
@Bean("masterDataSource")
@ConfigurationProperties(prefix = "spring.druid.datasource.master")
DataSource masterDataSource(){
log.info("create master datasource...");
return DataSourceBuilder.create().build();
}
@Bean("slaveDataSource")
@ConfigurationProperties(prefix = "spring.druid.datasource.slave")
DataSource slaveDataSource(){
log.info("create slave datasource...");
return DataSourceBuilder.create().build();
}
@Bean
@Primary
DataSource primaryDataSource(
@Autowired @Qualifier("masterDataSource") DataSource masterDataSource,
@Autowired @Qualifier("slaveDataSource") DataSource slaveDataSource) {
log.info("create routing datasource...");
Map<Object, Object> map = new HashMap<>();
map.put("masterDataSource", masterDataSource);
map.put("slaveDataSource", slaveDataSource);
RoutingDataSource routing = new RoutingDataSource();
routing.setTargetDataSources(map);
routing.setDefaultTargetDataSource(masterDataSource);
return routing;
}
}
3.创建动态数据源
public class RoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return RoutingDataSourceContext.getDataSourceRoutingKey();
}
}
4.利用ThreadLocal动态获取数据源
public class RoutingDataSourceContext {
static final ThreadLocal<String> threadLocalDataSourceKey = new ThreadLocal<>();
public static String getDataSourceRoutingKey() {
String key = threadLocalDataSourceKey.get();
return key == null ? "masterDataSource" : key;
}
public RoutingDataSourceContext(String key) {
threadLocalDataSourceKey.set(key);
}
public void close() {
threadLocalDataSourceKey.remove();
}
}
5.添加切面和注解方面动态获取
@Aspect
@Component
public class RoutingAspect {
@Around("@annotation(routingWith)")
public Object routingWithDataSource(ProceedingJoinPoint joinPoint, RoutingWith routingWith) throws Throwable{
String key = routingWith.value();
RoutingDataSourceContext routingDataSourceContext = new RoutingDataSourceContext(key);
return joinPoint.proceed();
}
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RoutingWith {
String value() default "masterDataSource";
}
6.创建对应的业务代码
@Slf4j
@RestController
public class DemoController {
@Autowired
private UserService userService;
@RequestMapping("/demo")
public void demo(){
userService.getUserByMaster();
userService.getUserBySlave();
}
}
public interface UserService {
public List<User> getUserByMaster();
public List<User> getUserBySlave();
}
@Slf4j
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@RoutingWith
@Override
public List<User> getUserByMaster() {
log.info("masterDataSource : {}" ,userMapper.getUser());
return userMapper.getUser();
}
@RoutingWith("slaveDataSource")
@Override
public List<User> getUserBySlave() {
log.info("slaveDataSource : {}" ,userMapper.getUser());
return userMapper.getUser();
}
}
@Repository
public interface UserMapper {
List<User> getUser();
User getUserById();
}
<?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="com.jhy.mapper.UserMapper">
<resultMap id="user" type="com.jhy.pojo.User">
<result property="id" column="id"/>
<result property="userName" column="user_name"/>
<result property="age" column="age"/>
</resultMap>
<select id="getUser" resultMap="user">
select * from user
</select>
<select id="getUserById" resultType="com.jhy.pojo.User">
select * from user where id = 1
</select>
</mapper>
@Data
public class User {
private Integer id;
private String userName;
private Integer age;
}
7.启动访问
@SpringBootApplication
@MapperScan("com.jhy.mapper")
public class SpringbootDynamicCustomApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootDynamicCustomApplication.class, args);
}
}