4. springboot动态数据源配置之自定义

目录

1.项目搭建好后先添加配置文件

2.自定义数据源

3.创建动态数据源

4.利用ThreadLocal动态获取数据源

5.添加切面和注解方面动态获取

6.创建对应的业务代码

7.启动访问


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);
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值