Spring动态数据源的简单理解

连接数据库时,需要url,userName,和password,怎么做到动态呢,那就是在使用时,根据你的设置,去连接不同的url,userName,和password,实现数据源的切换。

1.先写一个类来放数据源的key。

public class DataSourceKeyHolder {
    private static final ThreadLocal<String> keyHolder = new ThreadLocal<>();

    public static void setKey(String key) {
        keyHolder.remove();
        keyHolder.set(key);
    }

    public static String getKey() {
        String s = keyHolder.get();
        Assert.notNull(s, "key 不能为空");
        return s;
    }
    public static void clear(){
        keyHolder.remove();
    }
}

2.写一个类继承extends AbstractRoutingDataSource

public class MyDynamicDataSource extends AbstractRoutingDataSource{

    /**
     * Determine the current lookup key. This will typically be
     * implemented to check a thread-bound transaction context.
     * <p>Allows for arbitrary keys. The returned key needs
     * to match the stored lookup key type, as resolved by the
     * {@link #resolveSpecifiedLookupKey} method.
     */
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceKeyHolder.getKey();
    }
}
可以看到重写了determineCurrentLookupKey方法,里面的key值是取的DataSourceKeyHolder类线程里面我们自定义的key。
重写的determineCurrentLookupKey会根据你自定义的key取出resolvedDataSources这个map中的DataSource

 3.以@Bean注入需要连接的数据库参数。

@Configuration
public class DynamicSataSourceConfig {

    @Bean
    public DriverManagerDataSource dataSource1() {
        String url = "jdbc:mysql://localhost:3306/whw_test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai\n";
        String userName = "root";
        String password = "zaq12wsX";
        return new DriverManagerDataSource(url, userName, password);
    }

    @Bean
    public DriverManagerDataSource dataSource2() {
        String url = "jdbc:mysql://localhost:3306/whw_test2?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai\n";
        String userName = "root";
        String password = "zaq12wsX";
        return new DriverManagerDataSource(url, userName, password);
    }

    @Bean
    public DriverManagerDataSource dataSource3() {
        String url = "jdbc:mysql://localhost:3306/whw_test3?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai\n";
        String userName = "root";
        String password = "zaq12wsX";
        return new DriverManagerDataSource(url, userName, password);
    }

    @Bean
    public MyDynamicDataSource dynamicDataSource(Map<String, DriverManagerDataSource> map) {
        HashMap<Object, Object> original = new HashMap<>(map);
        MyDynamicDataSource myDynamicDataSource = new MyDynamicDataSource();
        myDynamicDataSource.setTargetDataSources(original);
        return myDynamicDataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(AbstractRoutingDataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

}

setTargetDataSources方法  把@Bean注入的数据源参数,从targetDataSources复制到resolvedDataSources这个map。

 4.写个测试类

public class DynamicSataSourceTest {
    public static void main(String[] args) {
        try {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DynamicSataSourceConfig.class);
            JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class);
            dataSource1(jdbcTemplate);
            dataSource2(jdbcTemplate);
            dataSource3(jdbcTemplate);
        }catch (Exception e){
            e.printStackTrace();
        }

    }
    public static void dataSource1(	JdbcTemplate jdbcTemplate ){
        DataSourceKeyHolder.setKey("dataSource1");
        try {
            UserBean testBean = jdbcTemplate.queryForObject("select * from t_test where id=?", new BeanPropertyRowMapper<>(UserBean.class), 1);
            System.out.println(testBean);
        }finally {
            DataSourceKeyHolder.clear();
        }
    }
    public static void dataSource2(	JdbcTemplate jdbcTemplate ){
        DataSourceKeyHolder.setKey("dataSource2");
        try {
            UserBean testBean = jdbcTemplate.queryForObject("select * from t_test where id=?", new BeanPropertyRowMapper<>(UserBean.class), 1);
            System.out.println(testBean);
        }finally {
            DataSourceKeyHolder.clear();
        }
    }
    public static void dataSource3(	JdbcTemplate jdbcTemplate ){
        DataSourceKeyHolder.setKey("dataSource3");
        try {
            UserBean testBean = jdbcTemplate.queryForObject("select * from t_test where id=?", new BeanPropertyRowMapper<>(UserBean.class), 1);
            System.out.println(testBean);
        }finally {
            DataSourceKeyHolder.clear();
        }
    }
}

需要连接哪个数据库,在使用sql前DataSourceKeyHolder.setKey("dataSource1");

然后根据我们设定的 数据源key去读取相应的DataSource。

输出结果:

 UserBean(id=1, name=test_mary, age=3.0)
UserBean(id=1, name=test2_mary, age=3.0)
UserBean(id=1, name=test3_mary, age=3.0)

 切换成功。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值