Spring Boot2.3.2 + Druid1.1.22
druid jar包
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid-version}</version>
</dependency>
properties 配置文件
#mysql
spring.datasource.druid.ds1.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.druid.ds1.url=jdbc:mysql://ip:3306/数据库名?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai&allowMultiQueries=true
spring.datasource.druid.ds1.username=用户名
spring.datasource.druid.ds1.password=密码
spring.datasource.druid.ds1.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.ds2.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.druid.ds2.url=jdbc:mysql:ip:3306/数据库名?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai&allowMultiQueries=true
spring.datasource.druid.ds2.username=用户名
spring.datasource.druid.ds2.password=密码
spring.datasource.druid.ds2.type=com.alibaba.druid.pool.DruidDataSource
#config druid
#连接池的设置
#初始化时建立物理连接的个数
spring.datasource.druid.initialSize=5
#最小连接池数量
spring.datasource.druid.minIdle=5
#最大连接池数量 maxIdle已经不再使用
spring.datasource.druid.maxActive=20
#获取连接时最大等待时间,单位毫秒
spring.datasource.druid.max-wait=60000
#申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
spring.datasource.druid.test-while-idle=true
#既作为检测的间隔时间又作为testWhileIdel执行的依据
spring.datasource.druid.time-between-eviction-runs-millis=60000
#销毁线程时检测当前连接的最后活动时间和当前时间差大于该值时,关闭当前连接
spring.datasource.druid.min-evictable-idle-time-millis=30000
#用来检测连接是否有效的sql 必须是一个查询语句
#mysql中为 select 'x'
#oracle中为 select 1 from dual
spring.datasource.druid.validation-query=select 'x'
#申请连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
spring.datasource.druid.test-on-borrow=false
#归还连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
spring.datasource.druid.test-on-return=false
#当数据库抛出不可恢复的异常时,抛弃该连接
#spring.datasource.druid.exception-sorter=true
#是否缓存preparedStatement,mysql5.5+建议开启
#spring.datasource.druid.pool-prepared-statements=true
#当值大于0时poolPreparedStatements会自动修改为true
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
#配置扩展插件
#spring.datasource.druid.filters=stat,wall
#通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
#合并多个DruidDataSource的监控数据
spring.datasource.druid.use-global-data-source-stat=true
#设置访问druid监控页的账号和密码,默认没有
spring.datasource.druid.stat-view-servlet.login-username=test
spring.datasource.druid.stat-view-servlet.login-password=123456
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.stat-view-servlet.reset-enable=true
spring.datasource.druid.stat-view-servlet.allow=
spring.datasource.druid.stat-view-servlet.deny=
spring.datasource.druid.multiStatementAllow=true
启动文件
@SpringBootApplication(
exclude = DataSourceAutoConfiguration.class
)
@EnableTransactionManagement
@EnableAspectJAutoProxy(exposeProxy = true)
@Import(DataSourceConfig.class)
public class AdminApplication {
public static void main(String[] args) {
SpringApplication.run(AdminApplication.class, args);
}
}
多数据源配置
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.boot.context.properties.ConfigurationProperties;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DataSourceConfig {
/**
* 数据源1
* @return
*/
@Bean
@ConfigurationProperties("spring.datasource.druid.ds1")
public DataSource firstDataSource(){
return DruidDataSourceBuilder.create().build();
}
/**
* 数据源2
* @return
*/
@Bean
@ConfigurationProperties("spring.datasource.druid.ds2")
public DataSource secondDataSource(){
return DruidDataSourceBuilder.create().build();
}
/**
*
* @param firstDataSource
* @param secondDataSource
* @return
* Primary 是默认的数据源
* DynamicDataSource用来坐数据源的切换
*/
@Bean
@Primary
public DynamicDataSource dataSource(DataSource firstDataSource, DataSource secondDataSource) {
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DataSourceNames.FIRST, firstDataSource);
targetDataSources.put(DataSourceNames.SECOND, secondDataSource);
return new DynamicDataSource(firstDataSource, targetDataSources);
}
}
多数据源枚举
public class DataSourceNames {
static String FIRST = "ds1";
static String SECOND = "ds2";
}
动态数据源
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import javax.sql.DataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
//默认数据源
public static final String DEFAULT_DS = "ds1";
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
/**
* 设置多数据源和默认的方法
* @param defaultTargetDataSource
* @param targetDataSources
*/
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
/**
* 实现AbstractRoutingDataSource并重写determineCurrentLookupKey()方法
* 就是这个方法获取数据源的
* @return
*/
@Override
protected Object determineCurrentLookupKey() {
return getDataSource();
}
/**
* 设置key
* @param dataSource
*/
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
/**
* 获取key
* @return
*/
public static String getDataSource() {
return contextHolder.get();
}
/**
* 用了就清除
*/
public static void clearDataSource() {
contextHolder.remove();
}
}
多数据源用注解来切换
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
String value() default "ds1";
}
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class DynamicDataSourceAspect {
/**
* 注解之前调用
* @param point
*/
@Before("@annotation(DataSource)")
public void beforeSwitchDS(JoinPoint point){
//获得当前访问的class
Class<?> className = point.getTarget().getClass();
//获得访问的方法名
String methodName = point.getSignature().getName();
//得到方法的参数的类型
Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
String dataSource = DynamicDataSource.DEFAULT_DS;
try {
// 得到访问的方法对象
Method method = className.getMethod(methodName, argClass);
// 判断是否存在@DS注解
if (method.isAnnotationPresent(DataSource.class)) {
DataSource annotation = method.getAnnotation(DataSource.class);
// 取出注解中的数据源名
dataSource = annotation.value();
DynamicDataSource.setDataSource(dataSource);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 注解之后调用
* @param point
*/
@After("@annotation(DataSource)")
public void afterSwitchDS(JoinPoint point){
DynamicDataSource.clearDataSource();
}
}
然后方法下面加如下注解就可以了
版权声明:本文为qq_38999509原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。