Spring Boot 多数据源配置(springboot多数据源配置和切换oracle)

  本篇文章为你整理了Spring Boot 多数据源配置(springboot多数据源配置和切换oracle)的详细内容,包含有springboot多数据源配置mybatis springboot多数据源配置和切换oracle springboot多数据源配置druid springboot多数据源配置pg Spring Boot 多数据源配置,希望能帮助你了解 Spring Boot 多数据源配置。

  1.1. 手动切换数据源

  application.properties

  

# Order

 

  # 如果用Druid作为数据源,应该用url属性,而不是jdbc-url

  spring.datasource.order.jdbc-url=jdbc:mysql://localhost:3306/order?useUnicode=true characterEncoding=utf8 allowMultiQueries=true useSSL=false

  spring.datasource.order.username=root

  spring.datasource.order.password=123456

  spring.datasource.order.driver-class-name=com.mysql.cj.jdbc.Driver

  # Stock

  spring.datasource.stock.jdbc-url=jdbc:mysql://localhost:3306/stock?useUnicode=true characterEncoding=utf8 allowMultiQueries=true useSSL=false

  spring.datasource.stock.username=root

  spring.datasource.stock.password=123456

  spring.datasource.stock.driver-class-name=com.mysql.cj.jdbc.Driver

  # Account

  spring.datasource.account.jdbc-url=jdbc:mysql://localhost:3306/account?useUnicode=true characterEncoding=utf8 allowMultiQueries=true useSSL=false

  spring.datasource.account.username=root

  spring.datasource.account.password=123456

  spring.datasource.account.driver-class-name=com.mysql.cj.jdbc.Driver

 

  配置数据源

  DataSourceConfig.java

  

package com.cjs.example.config;

 

  import com.alibaba.druid.pool.DruidDataSource;

  import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;

  import com.zaxxer.hikari.HikariDataSource;

  import org.mybatis.spring.SqlSessionFactoryBean;

  import org.springframework.beans.factory.annotation.Qualifier;

  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.core.io.support.PathMatchingResourcePatternResolver;

  import javax.sql.DataSource;

  import java.util.HashMap;

  import java.util.Map;

  @Configuration

  public class DataSourceConfig {

   @Bean("orderDataSource")

   @ConfigurationProperties(prefix = "spring.datasource.order")

   public DataSource orderDataSource() {

  // return new HikariDataSource();

  // return new DruidDataSource();

   return DataSourceBuilder.create().build();

   @Bean("accountDataSource")

   @ConfigurationProperties(prefix = "spring.datasource.account")

   public DataSource accountDataSource() {

  // return new HikariDataSource();

  // return new DruidDataSource();

   return DataSourceBuilder.create().build();

   @Bean("stockDataSource")

   @ConfigurationProperties(prefix = "spring.datasource.stock")

   public DataSource stockDataSource() {

  // return new HikariDataSource();

  // return new DruidDataSource();

   return DataSourceBuilder.create().build();

   @Primary

   @Bean("dynamicDataSource")

   public DataSource dynamicDataSource(@Qualifier("orderDataSource") DataSource orderDataSource,

   @Qualifier("accountDataSource") DataSource accountDataSource,

   @Qualifier("stockDataSource") DataSource stockDataSource) {

   Map Object, Object dataSourceMap = new HashMap (3);

   dataSourceMap.put(DataSourceKey.ORDER.name(), orderDataSource);

   dataSourceMap.put(DataSourceKey.STOCK.name(), stockDataSource);

   dataSourceMap.put(DataSourceKey.ACCOUNT.name(), accountDataSource);

   DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();

   dynamicRoutingDataSource.setDefaultTargetDataSource(orderDataSource);

   dynamicRoutingDataSource.setTargetDataSources(dataSourceMap);

   return dynamicRoutingDataSource;

   /* https://baomidou.com/pages/3b5af0/ */

   @Bean

   public MybatisSqlSessionFactoryBean sqlSessionFactoryBean(@Qualifier("dynamicDataSource") DataSource dataSource) {

   MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();

   sqlSessionFactoryBean.setDataSource(dataSource);

  // sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*.xml"));

   return sqlSessionFactoryBean;

  }

 

  由于是MyBatsi-Plus,所以配的是MybatisSqlSessionFactoryBean,如果是MyBatis,则应该是SqlSessionFactoryBean

  DataSourceKey.java

  

package com.cjs.example.config;

 

  public enum DataSourceKey {

   * Order data source key.

   ORDER,

   * Stock data source key.

   STOCK,

   * Account data source key.

   ACCOUNT

  }

 

  DynamicDataSourceContextHolder.java

  

package com.cjs.example.config;

 

  public class DynamicDataSourceContextHolder {

   private static final ThreadLocal String CONTEXT_HOLDER = ThreadLocal.withInitial(DataSourceKey.ORDER::name);

   public static void setDataSourceKey(DataSourceKey key) {

   CONTEXT_HOLDER.set(key.name());

   public static String getDataSourceKey() {

   return CONTEXT_HOLDER.get();

   public static void clearDataSourceKey() {

   CONTEXT_HOLDER.remove();

  }

 

  DynamicRoutingDataSource.java

  

package com.cjs.example.config;

 

  import lombok.extern.slf4j.Slf4j;

  import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

  @Slf4j

  public class DynamicRoutingDataSource extends AbstractRoutingDataSource {

   @Override

   protected Object determineCurrentLookupKey() {

   log.info("当前数据源 [{}]", DynamicDataSourceContextHolder.getDataSourceKey());

   return DynamicDataSourceContextHolder.getDataSourceKey();

  }

 

  好了,配置完以后,在操作数据库之前,先设置用哪个数据源即可,就像下面这样:

  

DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.ACCOUNT);

 

  举个例子:

  

package com.cjs.example;

 

  import com.cjs.example.account.entity.Account;

  import com.cjs.example.account.service.IAccountService;

  import com.cjs.example.config.DataSourceKey;

  import com.cjs.example.config.DynamicDataSourceContextHolder;

  import com.cjs.example.order.entity.Order;

  import com.cjs.example.order.service.IOrderService;

  import com.cjs.example.stock.entity.Stock;

  import com.cjs.example.stock.service.IStockService;

  import org.junit.jupiter.api.Test;

  import org.springframework.beans.factory.annotation.Autowired;

  import org.springframework.boot.test.context.SpringBootTest;

  import java.math.BigDecimal;

  @SpringBootTest

  public class Demo1122ApplicationTests {

   @Autowired

   private IOrderService orderService;

   @Autowired

   private IAccountService accountService;

   @Autowired

   private IStockService stockService;

   @Test

   public void doBusiness() {

   DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.ORDER);

   Order order = new Order();

   order.setOrderNo("123");

   order.setUserId("1");

   order.setCommodityCode("abc");

   order.setCount(1);

   order.setAmount(new BigDecimal("9.9"));

   orderService.save(order);

   DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.STOCK);

   Stock stock = new Stock();

   stock.setId(1);

   stock.setCommodityCode("abc");

   stock.setName("huawei");

   stock.setCount(1);

   stockService.updateById(stock);

   DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.ACCOUNT);

   Account account = new Account();

   account.setId(1);

   account.setUserId("1");

   account.setAmount(new BigDecimal(100));

   accountService.updateById(account);

  }

 

  这样写看起来确实有些麻烦,通常可能不会像这样在一个方法里操作多个数据库,就比如说假设这是一个管理后台,为了图省事把所有业务都写在这一个项目里,这个时候就需要配置多个数据源,各个数据库的业务互相没有关联,只是写在同一个项目中而已,这样的话如果每次都手动设置数据源太麻烦,可以定义一个AOP切面来自动切换数据源。

  1.2. 自动切换数据源

  https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop-ataspectj

  給刚才的代码升个级,利用AOP来拦截目标方法自动切换数据源

  1、添加@EnableAspectJAutoProxy注解

  

package com.cjs.example;

 

  import org.mybatis.spring.annotation.MapperScan;

  import org.springframework.boot.SpringApplication;

  import org.springframework.boot.autoconfigure.SpringBootApplication;

  import org.springframework.context.annotation.EnableAspectJAutoProxy;

  @EnableAspectJAutoProxy

  @MapperScan("com.cjs.example.*.mapper")

  @SpringBootApplication

  public class Demo1122Application {

   public static void main(String[] args) {

   SpringApplication.run(Demo1122Application.class, args);

  }

 

  2、定义切面、切点、通知

  

package com.cjs.example.aop;

 

  import com.cjs.example.config.DataSourceKey;

  import com.cjs.example.config.DynamicDataSourceContextHolder;

  import org.aspectj.lang.ProceedingJoinPoint;

  import org.aspectj.lang.annotation.Around;

  import org.aspectj.lang.annotation.Aspect;

  import org.aspectj.lang.annotation.Pointcut;

  import org.springframework.stereotype.Component;

  @Aspect

  @Component

  public class DataSourceAdvice {

  // @Pointcut("within(com.cjs.example.order..*)")

   @Pointcut("execution(* com.cjs.example.order..*.*(..))")

   public void orderPointcut() {}

  // @Pointcut("within(com.cjs.example.account..*)")

   @Pointcut("execution(* com.cjs.example.account..*.*(..))")

   public void accountPointcut() {}

  // @Pointcut("within(com.cjs.example.stock..*)")

   @Pointcut("execution(* com.cjs.example.stock..*.*(..))")

   public void stockPointcut() {}

  
@Around("orderPointcut()")

   public Object order(ProceedingJoinPoint pjp) throws Throwable {

   DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.ORDER);

   Object retVal = pjp.proceed();

   DynamicDataSourceContextHolder.clearDataSourceKey();

   return retVal;

   @Around("accountPointcut()")

   public Object account(ProceedingJoinPoint pjp) throws Throwable {

   DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.ACCOUNT);

   Object retVal = pjp.proceed();

   DynamicDataSourceContextHolder.clearDataSourceKey();

   return retVal;

   @Around("stockPointcut()")

   public Object stock(ProceedingJoinPoint pjp) throws Throwable {

   DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.STOCK);

   Object retVal = pjp.proceed();

   DynamicDataSourceContextHolder.clearDataSourceKey();

   return retVal;

  }

 

  现在就不用每次调用service方法前手动设置数据源了

  工程结构

  第二种方式:dynamic-datasource-spring-boot-starter

  功能很强大,支持 数据源分组,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式

  https://github.com/baomidou/dynamic-datasource-spring-boot-starter

  1、引入dynamic-datasource-spring-boot-starter

  

 dependency 

 

   groupId com.baomidou /groupId

   artifactId dynamic-datasource-spring-boot-starter /artifactId

   version 3.5.2 /version

   /dependency

 

  2、配置数据源

  

spring:

 

   datasource:

   dynamic:

   primary: master #设置默认的数据源或者数据源组,默认值即为master

   strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源

   datasource:

   master:

   url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic

   username: root

   password: 123456

   driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置

   slave_1:

   url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic

   username: root

   password: 123456

   driver-class-name: com.mysql.jdbc.Driver

   slave_2:

   url: ENC(xxxxx) # 内置加密,使用请查看详细文档

   username: ENC(xxxxx)

   password: ENC(xxxxx)

   driver-class-name: com.mysql.jdbc.Driver

   #......省略

   #以上会配置一个默认库master,一个组slave下有两个子库slave_1,slave_2

 

  主从配置,读写分离

  

# 多主多从 纯粹多库(记得设置primary) 混合配置

 

  spring: spring: spring:

   datasource: datasource: datasource:

   dynamic: dynamic: dynamic:

   datasource: datasource: datasource:

   master_1: mysql: master:

   master_2: oracle: slave_1:

   slave_1: sqlserver: slave_2:

   slave_2: postgresql: oracle_1:

   slave_3: h2: oracle_2:

 

  改造一下前面的例子

  

spring.datasource.dynamic.primary=order

 

  # Order

  spring.datasource.dynamic.datasource.order.url=jdbc:mysql://localhost:3306/order?useUnicode=true characterEncoding=utf8 allowMultiQueries=true useSSL=false

  spring.datasource.dynamic.datasource.order.username=root

  spring.datasource.dynamic.datasource.order.password=123456

  spring.datasource.dynamic.datasource.order.driver-class-name=com.mysql.cj.jdbc.Driver

  # Stock

  spring.datasource.dynamic.datasource.stock.url=jdbc:mysql://localhost:3306/stock?useUnicode=true characterEncoding=utf8 allowMultiQueries=true useSSL=false

  spring.datasource.dynamic.datasource.stock.username=root

  spring.datasource.dynamic.datasource.stock.password=123456

  spring.datasource.dynamic.datasource.stock.driver-class-name=com.mysql.cj.jdbc.Driver

  # Account

  spring.datasource.dynamic.datasource.account.url=jdbc:mysql://localhost:3306/account?useUnicode=true characterEncoding=utf8 allowMultiQueries=true useSSL=false

  spring.datasource.dynamic.datasource.account.username=root

  spring.datasource.dynamic.datasource.account.password=123456

  spring.datasource.dynamic.datasource.account.driver-class-name=com.mysql.cj.jdbc.Driver

 

  3、使用@DS切换数据源

  @DS可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解

  
import com.baomidou.dynamic.datasource.annotation.DS;

  import com.cjs.example.order.entity.Order;

  import com.cjs.example.order.mapper.OrderMapper;

  import com.cjs.example.order.service.IOrderService;

  import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

  import org.springframework.stereotype.Service;

  @DS("order")

  @Service

  public class OrderServiceImpl extends ServiceImpl OrderMapper, Order implements IOrderService {

  }

 

 

  

package com.cjs.example.stock.service.impl;

 

  import com.baomidou.dynamic.datasource.annotation.DS;

  import com.cjs.example.stock.entity.Stock;

  import com.cjs.example.stock.mapper.StockMapper;

  import com.cjs.example.stock.service.IStockService;

  import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

  import org.springframework.stereotype.Service;

  @DS("stock")

  @Service

  public class StockServiceImpl extends ServiceImpl StockMapper, Stock implements IStockService {

  }

 

  

package com.cjs.example.account.service.impl;

 

  import com.baomidou.dynamic.datasource.annotation.DS;

  import com.cjs.example.account.entity.Account;

  import com.cjs.example.account.mapper.AccountMapper;

  import com.cjs.example.account.service.IAccountService;

  import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

  import org.springframework.stereotype.Service;

  @DS("account")

  @Service

  public class AccountServiceImpl extends ServiceImpl AccountMapper, Account implements IAccountService {

  }

 

  

  以上就是Spring Boot 多数据源配置(springboot多数据源配置和切换oracle)的详细内容,想要了解更多 Spring Boot 多数据源配置的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: