当前位置: 首页 > news >正文

springboot整合druid(多数据源配置)

一、pom引入

 
<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.10</version>
</dependency>
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version>
</dependency>

二、yml文件配置

multiple: true
spring:datasource:primary:hikari:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 1234ABcdtype: com.alibaba.druid.pool.DruidDataSourcejdbc-url: jdbc:mysql://192.168.30.132:23306/test1?characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=true&allowMultiQueries=truesecondary:hikari:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 1q2w3e4r5ttype: com.alibaba.druid.pool.DruidDataSourcejdbc-url: jdbc:mysql://192.168.30.136:43306/test2?characterEncoding=utf-8&serverTimezone=Hongkong&useSSL=true&allowMultiQueries=true&zeroDateTimeBehavior=convertToNulldruid:initial-size: 10min-idle: 10max-active: 100max-wait: 60000time-between-eviction-runs-millis: 2000min-evictable-idle-time-millis: 300000validation-query: SELECT 1test-while-idle: truetest-on-borrow: falsetest-on-return: falsepool-prepared-statements: falsemax-pool-prepared-statement-per-connection-size: 20use-global-data-source-stat: true

三、DataSourceName注解


import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface DataSourceName {/*** 指定数据源名称* @return dataSourceName*/String value() default "primary";
}

四、DynamicDataSourceAspect

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;@Aspect
@Component
public class DynamicDataSourceAspect {@Before("@annotation(dataSourceName)")public void beforeSwitchDataSource(DataSourceName dataSourceName){// 切换数据源DataSourceNameContextHolder.setDataSourceName(dataSourceName.value());}@After("@annotation(com.sgcc.dlsc.pxsettelementinfpubquery.config.DB.DataSourceName)")public void afterSwitchDataSource(){DataSourceNameContextHolder.resetDataSourceName();}
}

五、DynamicDataSourceRouter

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;import java.io.PrintWriter;
import java.sql.SQLException;public class DynamicDataSourceRouter extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DataSourceNameContextHolder.getDataSourceName();}@Overridepublic void setLogWriter(PrintWriter pw) throws SQLException {super.setLogWriter(pw);}
}

六、DataSourceConfig


import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;@Configuration
// 自定义数据源一定要排除SpringBoot自动配置数据源,不然会出现循环引用的问题,The dependencies of some of the beans in the application context form a cycle
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
@ConditionalOnProperty(name = "multiple",havingValue = "true")
public class DataSourceConfig {@Bean(name = "primary")@ConfigurationProperties(prefix = "spring.datasource.primary.hikari")public DataSource primaryDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "secondary")@ConfigurationProperties(prefix = "spring.datasource.secondary.hikari")public DataSource secondaryDataSource() {return DataSourceBuilder.create().build();}/*** 动态数据源* 通过AOP+注解实现动态切换** @return*/@Primary@Bean(name = "dynamicDataSource")public DataSource dataSource() {DynamicDataSourceRouter dynamicDataSource = new DynamicDataSourceRouter();// 默认数据源dynamicDataSource.setDefaultTargetDataSource(primaryDataSource());// 配置多数据源Map<Object, Object> dataSourceMap = new HashMap(5);dataSourceMap.put("primary", primaryDataSource());dataSourceMap.put("secondary", secondaryDataSource());dynamicDataSource.setTargetDataSources(dataSourceMap);return dynamicDataSource;}/*** 配置@Transactional注解事物** @return*/@Beanpublic PlatformTransactionManager transactionManager() {return new DataSourceTransactionManager(dataSource());}}

七、DataSourceNameContextHolder

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.NamedThreadLocal;@Slf4j
public class DataSourceNameContextHolder {private static final ThreadLocal<String> dataSourceNameContextHolder = new NamedThreadLocal<>("DataSourceContext");/** 默认数据源名称 */public static final String DEFAULT_DATASOURCE_NAME = "primary";public static void setDataSourceName(String dataSourceName) {log.info("切换到[{}]数据源", dataSourceName);dataSourceNameContextHolder.set(dataSourceName);}public static String getDataSourceName() {return dataSourceNameContextHolder.get() != null ? dataSourceNameContextHolder.get() : DEFAULT_DATASOURCE_NAME;}public static void resetDataSourceName() {dataSourceNameContextHolder.remove();}
}

八、切换数据源

DataSourceNameContextHolder.setDataSourceName("secondary");

http://www.dtcms.com/a/349388.html

相关文章:

  • Python_occ 学习记录 | 阵列
  • 李沐-第十章-训练Seq2SeqAttentionDecoder报错
  • 十九、云原生分布式存储 CubeFS
  • 剧本杀APP系统开发:打造多元化娱乐生态的先锋力量
  • Go编写的轻量文件监控器. 可以监控终端上指定文件夹内的变化, 阻止删除,修改,新增操作. 可以用于AWD比赛或者终端应急响应
  • TensorFlow深度学习实战(34)——TensorFlow Probability
  • GO学习记录八——多文件封装功能+redis使用
  • Node.js(2)—— Buffer
  • 安卓Android低功耗蓝牙BLE连接异常报错133
  • Docker Compose 部署 Elasticsearch 8.12.2 集成 IK 中文分词器完整指南
  • Go初级三
  • 上海AI实验室突破扩散模型!GetMesh融合点云与三平面,重塑3D内容创作
  • 少儿舞蹈小程序需求规格说明书
  • AutoCAD Electrical缺少驱动程序“AceRedist“解决方法
  • 【STM32】G030单片机的独立看门狗
  • ELKB日志分析平台 部署
  • 完美世界招数据仓库工程师咯
  • ArcGIS JSAPI 高级教程 - 创建渐变色材质的自定义几何体
  • three.js+WebGL踩坑经验合集(8.3):合理设置camera.near和camera.far缓解实际场景中的z-fighting叠面问题
  • 大数据平台ETL任务导入分库分表数据
  • Jenkins+docker 微服务实现自动化部署安装和部署过程
  • TDengine IDMP 应用场景:电动汽车
  • AI测试工具midsence和browse_use的使用场景和差异
  • react+taro打包到不同小程序
  • Flutter旧版本升级-> Android 配置、iOS配置
  • 机器视觉的3C玻璃盖板丝印应用
  • KeepAlived+Haproxy实现负载均衡(SLB)
  • window显示驱动开发—混合系统 DDI 和 dList DLL 支持
  • Shell 循环编程:for 与 select 轻松入门
  • HTTP 与 HTTPS 深度解析:从原理到实际应用