当前位置:   article > 正文

Spring Boot + Druid动态数据源切换(注解实现)_spring.datasource.druid.max-active

spring.datasource.druid.max-active

Spring Boot2.3.2 + Druid1.1.22

druid jar包

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>druid</artifactId>
  4. <version>${druid-version}</version>
  5. </dependency>

properties 配置文件

  1. #mysql
  2. spring.datasource.druid.ds1.driverClassName=com.mysql.cj.jdbc.Driver
  3. spring.datasource.druid.ds1.url=jdbc:mysql://ip:3306/数据库名?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai&allowMultiQueries=true
  4. spring.datasource.druid.ds1.username=用户名
  5. spring.datasource.druid.ds1.password=密码
  6. spring.datasource.druid.ds1.type=com.alibaba.druid.pool.DruidDataSource
  7. spring.datasource.druid.ds2.driverClassName=com.mysql.cj.jdbc.Driver
  8. spring.datasource.druid.ds2.url=jdbc:mysql:ip:3306/数据库名?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai&allowMultiQueries=true
  9. spring.datasource.druid.ds2.username=用户名
  10. spring.datasource.druid.ds2.password=密码
  11. spring.datasource.druid.ds2.type=com.alibaba.druid.pool.DruidDataSource
  12. #config druid
  13. #连接池的设置
  14. #初始化时建立物理连接的个数
  15. spring.datasource.druid.initialSize=5
  16. #最小连接池数量
  17. spring.datasource.druid.minIdle=5
  18. #最大连接池数量 maxIdle已经不再使用
  19. spring.datasource.druid.maxActive=20
  20. #获取连接时最大等待时间,单位毫秒
  21. spring.datasource.druid.max-wait=60000
  22. #申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
  23. spring.datasource.druid.test-while-idle=true
  24. #既作为检测的间隔时间又作为testWhileIdel执行的依据
  25. spring.datasource.druid.time-between-eviction-runs-millis=60000
  26. #销毁线程时检测当前连接的最后活动时间和当前时间差大于该值时,关闭当前连接
  27. spring.datasource.druid.min-evictable-idle-time-millis=30000
  28. #用来检测连接是否有效的sql 必须是一个查询语句
  29. #mysql中为 select 'x'
  30. #oracle中为 select 1 from dual
  31. spring.datasource.druid.validation-query=select 'x'
  32. #申请连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
  33. spring.datasource.druid.test-on-borrow=false
  34. #归还连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
  35. spring.datasource.druid.test-on-return=false
  36. #当数据库抛出不可恢复的异常时,抛弃该连接
  37. #spring.datasource.druid.exception-sorter=true
  38. #是否缓存preparedStatement,mysql5.5+建议开启
  39. #spring.datasource.druid.pool-prepared-statements=true
  40. #当值大于0时poolPreparedStatements会自动修改为true
  41. spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
  42. #配置扩展插件
  43. #spring.datasource.druid.filters=stat,wall
  44. #通过connectProperties属性来打开mergeSql功能;慢SQL记录
  45. spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
  46. #合并多个DruidDataSource的监控数据
  47. spring.datasource.druid.use-global-data-source-stat=true
  48. #设置访问druid监控页的账号和密码,默认没有
  49. spring.datasource.druid.stat-view-servlet.login-username=test
  50. spring.datasource.druid.stat-view-servlet.login-password=123456
  51. spring.datasource.druid.stat-view-servlet.enabled=true
  52. spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
  53. spring.datasource.druid.stat-view-servlet.reset-enable=true
  54. spring.datasource.druid.stat-view-servlet.allow=
  55. spring.datasource.druid.stat-view-servlet.deny=
  56. spring.datasource.druid.multiStatementAllow=true

启动文件

  1. @SpringBootApplication(
  2. exclude = DataSourceAutoConfiguration.class
  3. )
  4. @EnableTransactionManagement
  5. @EnableAspectJAutoProxy(exposeProxy = true)
  6. @Import(DataSourceConfig.class)
  7. public class AdminApplication {
  8. public static void main(String[] args) {
  9. SpringApplication.run(AdminApplication.class, args);
  10. }
  11. }

多数据源配置

  1. import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.context.annotation.Primary;
  5. import org.springframework.boot.context.properties.ConfigurationProperties;
  6. import javax.sql.DataSource;
  7. import java.util.HashMap;
  8. import java.util.Map;
  9. @Configuration
  10. public class DataSourceConfig {
  11. /**
  12. * 数据源1
  13. * @return
  14. */
  15. @Bean
  16. @ConfigurationProperties("spring.datasource.druid.ds1")
  17. public DataSource firstDataSource(){
  18. return DruidDataSourceBuilder.create().build();
  19. }
  20. /**
  21. * 数据源2
  22. * @return
  23. */
  24. @Bean
  25. @ConfigurationProperties("spring.datasource.druid.ds2")
  26. public DataSource secondDataSource(){
  27. return DruidDataSourceBuilder.create().build();
  28. }
  29. /**
  30. *
  31. * @param firstDataSource
  32. * @param secondDataSource
  33. * @return
  34. * Primary 是默认的数据源
  35. * DynamicDataSource用来坐数据源的切换
  36. */
  37. @Bean
  38. @Primary
  39. public DynamicDataSource dataSource(DataSource firstDataSource, DataSource secondDataSource) {
  40. Map<Object, Object> targetDataSources = new HashMap<>();
  41. targetDataSources.put(DataSourceNames.FIRST, firstDataSource);
  42. targetDataSources.put(DataSourceNames.SECOND, secondDataSource);
  43. return new DynamicDataSource(firstDataSource, targetDataSources);
  44. }
  45. }

多数据源枚举

  1. public class DataSourceNames {
  2. static String FIRST = "ds1";
  3. static String SECOND = "ds2";
  4. }

动态数据源

  1. import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
  2. import java.sql.Connection;
  3. import java.sql.SQLException;
  4. import java.util.Map;
  5. import javax.sql.DataSource;
  6. public class DynamicDataSource extends AbstractRoutingDataSource {
  7. //默认数据源
  8. public static final String DEFAULT_DS = "ds1";
  9. private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
  10. /**
  11. * 设置多数据源和默认的方法
  12. * @param defaultTargetDataSource
  13. * @param targetDataSources
  14. */
  15. public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
  16. super.setDefaultTargetDataSource(defaultTargetDataSource);
  17. super.setTargetDataSources(targetDataSources);
  18. super.afterPropertiesSet();
  19. }
  20. /**
  21. * 实现AbstractRoutingDataSource并重写determineCurrentLookupKey()方法
  22. * 就是这个方法获取数据源的
  23. * @return
  24. */
  25. @Override
  26. protected Object determineCurrentLookupKey() {
  27. return getDataSource();
  28. }
  29. /**
  30. * 设置key
  31. * @param dataSource
  32. */
  33. public static void setDataSource(String dataSource) {
  34. contextHolder.set(dataSource);
  35. }
  36. /**
  37. * 获取key
  38. * @return
  39. */
  40. public static String getDataSource() {
  41. return contextHolder.get();
  42. }
  43. /**
  44. * 用了就清除
  45. */
  46. public static void clearDataSource() {
  47. contextHolder.remove();
  48. }
  49. }
多数据源用注解来切换
  1. import java.lang.annotation.*;
  2. @Target(ElementType.METHOD)
  3. @Retention(RetentionPolicy.RUNTIME)
  4. @Documented
  5. public @interface DataSource {
  6. String value() default "ds1";
  7. }
  1. import java.lang.reflect.Method;
  2. import org.aspectj.lang.JoinPoint;
  3. import org.aspectj.lang.annotation.After;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.aspectj.lang.annotation.Before;
  6. import org.aspectj.lang.reflect.MethodSignature;
  7. import org.springframework.stereotype.Component;
  8. @Aspect
  9. @Component
  10. public class DynamicDataSourceAspect {
  11. /**
  12. * 注解之前调用
  13. * @param point
  14. */
  15. @Before("@annotation(DataSource)")
  16. public void beforeSwitchDS(JoinPoint point){
  17. //获得当前访问的class
  18. Class<?> className = point.getTarget().getClass();
  19. //获得访问的方法名
  20. String methodName = point.getSignature().getName();
  21. //得到方法的参数的类型
  22. Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
  23. String dataSource = DynamicDataSource.DEFAULT_DS;
  24. try {
  25. // 得到访问的方法对象
  26. Method method = className.getMethod(methodName, argClass);
  27. // 判断是否存在@DS注解
  28. if (method.isAnnotationPresent(DataSource.class)) {
  29. DataSource annotation = method.getAnnotation(DataSource.class);
  30. // 取出注解中的数据源名
  31. dataSource = annotation.value();
  32. DynamicDataSource.setDataSource(dataSource);
  33. }
  34. } catch (Exception e) {
  35. e.printStackTrace();
  36. }
  37. }
  38. /**
  39. * 注解之后调用
  40. * @param point
  41. */
  42. @After("@annotation(DataSource)")
  43. public void afterSwitchDS(JoinPoint point){
  44. DynamicDataSource.clearDataSource();
  45. }
  46. }

然后方法下面加如下注解就可以了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/46565
推荐阅读
相关标签
  

闽ICP备14008679号