SpringBoot--Druid多数据源配置
SpringBoot--Druid多数据源配置| Id | Title | DateAdded | SourceUrl | PostType | Body | BlogId | Description | DateUpdated | IsMarkdown | EntryName | CreatedTime | IsActive | AutoDesc | AccessPermission |
| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------|
| 14813109| SpringBoot--Druid多数据源配置| 2021-05-26T13:48:00| | BlogPost|
最近整理了一下spring boot关于对多数据源的配置,记录下来:
一, 引入Jar包:
rokac.com<dependency> <!-- MySql驱动 --> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <!-- 连接池 --> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.
二, 配置参数:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
druid:
one: #数据源1
url: jdbc:mysql://localhost:3306/test1?...
username: root
password: root
two: #数据源2
url: jdbc:mysql://localhost:3306/test2?...
username: root
password: root
initial-size: 10
max-active: 100
min-idle: 10
max-wait: 60000
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
stat-view-servlet:
enabled: true
url-pattern: /druid/*
#login-username: admin
#login-password: admin
filter:
stat:
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
(参数配置,可参考: https://gitee.com/wenshao/druid/tree/master/druid-spring-boot-starter)
三, 编写配置文件:
1, 定义数据源名称常量 :
package com.gy.fast.common.config.data;/**
- 数据源名称
- @author geYang
- @date 2018-05-14
*/
public interface DataSourceNames {
String ONE = "ONE";
String TWO = "TWO";
}
2, 创建动态数据源:
package com.gy.fast.common.config.data;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import javax.sql.DataSource;
import java.util.Map;/**
动态数据源
@author geYang
@date 2018-05-14
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();/**
- 配置DataSource, defaultTargetDataSource为主数据库
*/
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}@Override
protected Object determineCurrentLookupKey() {
return getDataSource();
}public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}public static String getDataSource() {
return contextHolder.get();
}public static void clearDataSource() {
contextHolder.remove();
}}
3, 动态数据源配置:
package com.gy.fast.common.config.data;import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;/**
配置多数据源
@author geYang
@date 2018-05-14
*/
@Configuration
public class DynamicDataSourceConfig {/**
- 创建 DataSource Bean
- */
@Bean
@ConfigurationProperties("spring.datasource.druid.one")
public DataSource oneDataSource(){
DataSource dataSource = DruidDataSourceBuilder.create().build();
return dataSource;
}@Bean
@ConfigurationProperties("spring.datasource.druid.two")
public DataSource twoDataSource(){
DataSource dataSource = DruidDataSourceBuilder.create().build();
return dataSource;
}/**
- 如果还有数据源,在这继续添加 DataSource Bean
- */
@Bean
@Primary
public DynamicDataSource dataSource(DataSource oneDataSource, DataSource twoDataSource) {
Map<Object, Object> targetDataSources = new HashMap<>(2);
targetDataSources.put(DataSourceNames.ONE, oneDataSource);
targetDataSources.put(DataSourceNames.TWO, twoDataSource);
// 还有数据源,在targetDataSources中继续添加
System.out.println("DataSources:" + targetDataSources);
return new DynamicDataSource(oneDataSource, targetDataSources);
}
}
4, 定义动态数据源注解:
package com.gy.fast.common.config.data;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/**
- 多数据源注解
- @author geYang
- @date 2018-05-14
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
String value() default DataSourceNames.ONE;
}
5, 设置数据源 AOP 代理:
package com.gy.fast.common.config.data;import java.lang.reflect.Method;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;/**
数据源AOP切面处理
@author geYang
@date 2018-05-14
*/
@Aspect
@Component
public class DataSourceAspect implements Ordered {
protected Logger logger = LoggerFactory.getLogger(getClass());/**
- 切点: 所有配置 DataSource 注解的方法
*/
@Pointcut("@annotation(com.gy.fast.common.config.data.DataSource)")
public void dataSourcePointCut() {}@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
DataSource ds = method.getAnnotation(DataSource.class);
// 通过判断 DataSource 中的值来判断当前方法应用哪个数据源
DynamicDataSource.setDataSource(ds.value());
System.out.println("当前数据源: " + ds.value());
logger.debug("set datasource is " + ds.value());
try {
return point.proceed();
} finally {
DynamicDataSource.clearDataSource();
logger.debug("clean datasource");
}
}@Override
public int getOrder() {
return 1;
}
}
四, 修改启动文件:
package com.gy.fast;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Import;import com.gy.fast.common.config.data.DynamicDataSourceConfig;
/**
- 动态数据源配置,需要将自有的配置依赖(DynamicDataSourceConfig),将原有的依赖去除(DataSourceAutoConfiguration)
- @author geYang
- @date 2018-05-15
*/
@Import({DynamicDataSourceConfig.class})
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
public class FastApplication {
public static void main(String[] args) {
SpringApplication.run(FastApplication.class, args);
}
}
五, 配置完成, 进行测试:
package com.gy.fast;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import com.gy.fast.common.config.data.DataSource;
import com.gy.fast.common.config.data.DataSourceNames;
import com.gy.fast.module.sys.entity.SysUser;
import com.gy.fast.module.sys.service.SysUserService;/**
测试多数据源
@author geYang
@date 2018-05-15
*/
@Service
public class DataSourceTestService {
@Autowired
private SysUserService sysUserService;public SysUser test1(Long userId){
return sysUserService.selectById(userId);
}@DataSource(DataSourceNames.TWO)
public SysUser test2(Long userId){
return sysUserService.selectById(userId);
}
}
package com.gy.fast;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.gy.fast.module.sys.entity.SysUser;
@RunWith(SpringRunner.class)
@SpringBootTest
public class DynamicDataSourceTest {
@Autowired
private DataSourceTestService dataSourceTestService;
@Test
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> test(){
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 数据源ONE</span>
SysUser user1 = dataSourceTestService.test1(1L<span style="color: #000000;">);
System.out.println(ToStringBuilder.reflectionToString(user1));
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 数据源TWO</span>
SysUser user2 = dataSourceTestService.test2(1L<span style="color: #000000;">);
System.out.println(ToStringBuilder.reflectionToString(user2));
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 数据源ONE</span>
SysUser user3 = dataSourceTestService.test1(1L<span style="color: #000000;">);
System.out.println(ToStringBuilder.reflectionToString(user3));
}
}
| 648658| | 2021-05-26T13:52:00| false| | 2021-05-26T13:48:25.18| true| 最近整理了一下spring boot关于对多数据源的配置,记录下来: 一, 引入Jar包: <dependency> <!-- MySql驱动 --> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </d| Anonymous|
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)