SpringBoot项目如何实现同时连接PostgreSQL数据库和Oracal数据库

mac2026-06-18  4

application.yml的配置连接两个数据源

一个master,一个slave1:

spring: datasource: master: type: com.alibaba.druid.pool.DruidDataSource url: jdbc:postgresql://10.111.111.111:5432/aaa username: reta password: reta driver-class-name: org.postgresql.Driver name: master filters: stat slave1: type: com.alibaba.druid.pool.DruidDataSource username: reta password: reta driver-class-name: oracle.jdbc.OracleDriver url: jdbc:oracle:thin:@//10.111.11.112:1535/aaa name: slave1 filters: stat spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults: false spring.jpa.database-platform: org.hibernate.dialect.PostgreSQL9Dialect

注意,上面配置的最后两行,是因为要连接postgreSQL数据库才需要的。

新建一个包,存放相关配置文件。

接下来,将对图片中的文档进行说明。

DataSource

import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD }) public @interface DataSource { String value() default "master"; }

在这里设置默认连接的数据库master。

DataSourceContextHolder

public class DataSourceContextHolder { public static final String Master = "master"; public static final String Slave1 = "slave1"; private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); public static void setDataSource(String name){ contextHolder.set(name); } public static String getDataSource(){ return contextHolder.get(); } public static void cleanDataSource(){ contextHolder.remove(); } }

DynamicDataSource

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSource(); } }

DynamicDataSourceAspect

import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Aspect @Component @Order(1) //需要加入切面排序 public class DynamicDataSourceAspect { private Logger logger = LoggerFactory.getLogger(DynamicDataSourceAspect.class); //切入点只对@Service注解的类上的@DataSource方法生效 @Pointcut(value="@within(org.springframework.stereotype.Service) && @annotation(dataSource)" ) public void dynamicDataSourcePointCut(DataSource dataSource){} @Before(value = "dynamicDataSourcePointCut(dataSource)") public void switchDataSource(DataSource dataSource) throws Throwable{ logger.info("##############数据源 :{}###############",dataSource.value()); DataSourceContextHolder.setDataSource(dataSource.value()); } @After(value="dynamicDataSourcePointCut(dataSource)") public void after(DataSource dataSource){ DataSourceContextHolder.cleanDataSource(); } }

MultipleDateSourceConfig

import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Qualifier; 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; @Configuration public class MultipleDateSourceConfig { @Bean("master") @ConfigurationProperties(prefix = "spring.datasource.master") public DataSource creeateMasterDataSource(){ return new DruidDataSource(); } @Bean("slave1") @ConfigurationProperties(prefix = "spring.datasource.slave1") public DataSource creeateSlave1DataSource(){ return new DruidDataSource(); } /** * 设置动态数据源,通过@Primary 来确定主DataSource * @return */ @Bean @Primary public DataSource createDynamicdataSource(@Qualifier("master") DataSource master, @Qualifier("slave1") DataSource slave1){ DynamicDataSource dynamicDataSource = new DynamicDataSource(); //设置默认数据源 dynamicDataSource.setDefaultTargetDataSource(master); //配置多数据源 Map<Object, Object> map = new HashMap<>(); map.put("master",master); map.put("slave1",slave1); dynamicDataSource.setTargetDataSources(map); return dynamicDataSource; } }

在调用的时候,只需在service实现类中,注明数据库就好

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service public class InsertServiceImpl implements InsetService { @Autowired private InsertMapper insertMapper; @DataSource(DataSourceContextHolder.Slave1) @Transactional @Override public boolean insertDataForLastWeek(List<DataSyn> list) { return insertMapper.insertDataForLastWeek(list); } @DataSource(DataSourceContextHolder.Slave1) @Transactional @Override public int selectTotalNumber() { return insertMapper.selectTotalNumber(); } }

如此,便成功实现动态连接数据库。

最新回复(0)