赞
踩
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();
- }
- }

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

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。