使用JdbcTemplate来实现多数据源

使用JdbcTemplate来实现多数据源

实现思路:在配置文件中配置好数据源参数,通过构建DataSource将作为bean注册进容器,JdbcTemplate使用时从容器中拿取并切换
话不多说,直接开始正题

依赖

//其他的依赖省略,jdbc和数据库驱动依赖一定要有
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

数据源信息配置

multidatasource:
  - name: solvay
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://xx.xx.xx.xx:3306/xxx?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&useSSL=false
    username: xxx
    password: xxx
  - name: test
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&useSSL=false
    username: xxx
    password: xxx

构建多数据源并放入容器

从配置文件中读取到数据源信息


import lombok.Data;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.List;

@Data
@Component
@ConfigurationProperties(prefix = "spring")
public class DynamicDataSourceProperties implements Serializable {
    List<DataSourceProperties> multidatasource;
}

构建多数据源并手动注册到容器中


import com.solvay.datasource.DynamicDataSourceProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;

@Configuration
public class DynamicDataSourceConfig {

    //jdbcTemplate前缀
    public static final String jdbcTemplatePrefix = "JDBCTEMPLATE_";

    @Autowired
    DynamicDataSourceProperties dynamicDataSourceProperties;

    /**
    * @Author: syb
    * @Description: 获取配置文件的配置信息,手动配置数据源并向spring容器注册
    * @DateTime: 2022/7/27 8:31
    * @Params: 
    * @Return 
    */
    @PostConstruct
    private void registerDataSourceBean() {
        for (DataSourceProperties dataSourceProperties : dynamicDataSourceProperties.getMultidatasource()) {
            DataSource currDataSource = dataSourceProperties.initializeDataSourceBuilder().build();
            try {
                //动态注册bean对象
                registerBean(jdbcTemplatePrefix + dataSourceProperties.getName().toUpperCase(), JdbcTemplate.class, currDataSource);
                System.out.println("注册数据源成功:"+dataSourceProperties.getName());
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    private final ConfigurableApplicationContext applicationContext;

    public DynamicDataSourceConfig(ConfigurableApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public <T> T registerBean(String name, Class<T> clazz, Object... args) {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
        if (args.length > 0) {
            for (Object arg : args) {
                beanDefinitionBuilder.addConstructorArgValue(arg);
            }
        }
        BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
        BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) applicationContext.getBeanFactory();
        beanFactory.registerBeanDefinition(name, beanDefinition);
        return applicationContext.getBean(name, clazz);
    }

}

使用JdbcTemplate完成多数据源的查询

使用测试

JdbcTemplate jdbcTemplate = (JdbcTemplate) SpringContextUtil.getApplicationContext().getBean(jdbcTemplatePrefix + "SOLVAY");

        String sql="select * from sys_config limit 1";
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);

SpringContextUtil


import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
* @Author: syb
* @Description:
* @DateTime: 2022/7/27 9:22
* @Params:
* @Return
*/
@Component
public class SpringContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtil.applicationContext = applicationContext;
    }

    /**
    * @Author: syb
    * @Description: 获取applicationContext
    * @DateTime: 2022/7/27 9:22
    * @Params:
    * @Return
    */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
    * @Author: syb
    * @Description: 通过name获取 Bean.
    * @DateTime: 2022/7/27 9:22
    * @Params:
    * @Return
    */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
    * @Author: syb
    * @Description: 通过class获取Bean.
    * @DateTime: 2022/7/27 9:23
    * @Params:
    * @Return
    */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
    * @Author: syb
    * @Description: 通过name,以及Clazz返回指定的Bean
    * @DateTime: 2022/7/27 9:23
    * @Params: 
    * @Return 
    */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}
posted @   Cv工程师120621号  阅读(868)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示

目录导航