使用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);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了