Springboot configura múltiples fuentes de datos [explicación detallada]

Prefacio, ¿qué es una fuente de datos y un grupo de conexiones de bases de datos?

Antes de hablar sobre la configuración de múltiples fuentes de datos de SpringBoot, primero entendamos DataSource.
En java, hay muchas formas de operar la base de datos, además de JDBC, hay objetos DataSource de muchas maneras.

DataSource se puede considerar como una fuente de datos:
encapsula los parámetros de la base de datos, se conecta a la base de datos y opera el objeto DataSource en el programa para agregar, eliminar, modificar y consultar la base de datos.

Los objetos DataSource utilizados en diferentes métodos son diferentes. A continuación:

La clase DataSource en el marco dbcp es: org.apache.commons.dbcp.BasicDataSource
La clase DataSource en el marco c3p0 es: com.mchange.v2.c3p0.ComboPooledDataSource
La clase DataSource en el marco MyBatis es: org.apache.ibatis .datasource.pooled.PooledDataSource
La clase DataSource del marco Druid es: com.alibaba.druid.pool.DruidDataSource

Para algunas implementaciones de DataSource, a menudo se le llama grupo de conexión de base de datos ,

Por ejemplo, el documento oficial de Druid dice que "Druid es el mejor conjunto de conexiones de base de datos en el lenguaje Java". Solo se realiza el edificio central y muchos edificios periféricos se construyen sobre el núcleo.

La relación entre las fuentes de datos y los grupos de conexiones de bases de datos:

  • El origen de datos establece varias conexiones de base de datos, que se almacenan en el grupo de conexiones de base de datos.
  • Cuando necesite acceder a la base de datos, solo necesita obtener una conexión de base de datos inactiva del grupo de conexiones de la base de datos,
  • Cuando el programa termine de acceder a la base de datos, la conexión de la base de datos se volverá a colocar en el grupo de conexiones de la base de datos.

Cuando comenzamos a aprender JDBC, la operación de obtener una conexión de datos por nosotros mismos es la siguiente:
inserte la descripción de la imagen aquí
cuando aprendemos JDBC, usar directamente el formulario DriverManager generalmente requiere codificar el controlador en el proyecto (después de JDBC4.0, se puede registrar automáticamente el controlador) .

Y lo más importante es la conexión que se obtiene a través del método getConnection de DriverManager, que consiste en establecer una conexión con la base de datos.

Sin embargo, establecer una conexión con la base de datos es una tarea que consume muchos recursos y el establecimiento frecuente de la conexión a la base de datos generará una gran sobrecarga del sistema.

La conexión que se obtiene en DataSource proviene del pool de conexiones, aunque la conexión en el pool se obtiene fundamentalmente de DriverManager.

DataSource es una función alternativa de DriverManager, que tiene la capacidad de proporcionar conexiones externas.

A continuación, veamos cómo SpringBoot integra múltiples fuentes de datos.

1. Configure el archivo de configuración:

1. Dependencias de importación:

Si la fuente de datos de su nueva base de datos es diferente de la base de datos actual, recuerde introducir las dependencias del controlador de la nueva base de datos, como MySQL y PGSQL.

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>
 
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.2.7</version>
</dependency>

Primero, debe configurar la información de conexión de varias fuentes de datos en el archivo de configuración;

El archivo de configuración yml se usa aquí, y otros tipos de archivos de configuración son los mismos.
He configurado dos orígenes de datos, uno denominado origen de datos ds1 y otro denominado origen de datos ds2. Si desea configurar más orígenes de datos, simplemente continúe para agregarlos.

spring:
 # 数据源配置
  datasource:
    ds1: #数据源1
      driver-class-name: com.mysql.jdbc.Driver # mysql的驱动你可以配置别的关系型数据库
      url: jdbc:mysql://ip:3306/db1 #数据源地址
      username: root # 用户名
      password: root # 密码
    ds2: # 数据源2
      driver-class-name: com.mysql.jdbc.Driver # mysql的驱动你可以配置别的关系型数据库
      url: jdbc:mysql://ip:3307/db2#数据源地址
      username: root # 用户名
      password: root # 密码

2. Escriba la clase de configuración:

Escriba la clase de configuración de Springboot:

El principio de la conmutación de fuentes de datos múltiples de mybatis es llamar a diferentes fuentes de datos de acuerdo con diferentes paquetes,

Solo necesita escribir su mapper.java y mapper.xml en un paquete, y Springboot cambiará automáticamente las fuentes de datos por usted.

El código central son solo estas dos oraciones:

1. Se usa para especificar el escaneo de paquetes, especifique sqlSessionTemplateRef

@MapperScan(basePackages ="com.web.ds2.**.dao", 
            sqlSessionTemplateRef = "ds2SqlSessionTemplate")

2, utilizado para especificar la ruta de mapper.xml

sqlSessionFactory.
    setMapperLocations(new PathMatchingResourcePatternResolver().
                                getResources("classpath*:com/web/ds2/**/*.xml"));

El código detallado es el siguiente:

3. Configuración de la fuente de datos principal de Mybatis ds1:

/**
 * Mybatis主数据源ds1配置
 * 多数据源配置依赖数据源配置
 * @see  DataSourceConfig
 */
@Configuration
@MapperScan(basePackages ="com.web.ds1.**.dao", sqlSessionTemplateRef  = "ds1SqlSessionTemplate")
public class MybatisPlusConfig4ds1 {
    
    
 
    @Bean(name = "dataSource1")
    @ConfigurationProperties(prefix = "spring.datasource.ds1")
    @Primary
    public DataSource dataSource() {
    
    
        return DataSourceBuilder.create().build();
    }
 
    //主数据源 ds1数据源
    @Primary
    @Bean("ds1SqlSessionFactory")
    public SqlSessionFactory ds1SqlSessionFactory(@Qualifier("ds1DataSource") DataSource dataSource) throws Exception {
    
    
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(dataSource);
        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().
                        getResources("classpath*:com/web/ds1/**/*.xml"));  
        return sqlSessionFactory.getObject();
    }
 
    @Primary
    @Bean(name = "ds1TransactionManager")
    public DataSourceTransactionManager ds1TransactionManager(@Qualifier("ds1DataSource") DataSource dataSource) {
    
    
        return new DataSourceTransactionManager(dataSource);
    }
 
    @Primary
    @Bean(name = "ds1SqlSessionTemplate")
    public SqlSessionTemplate ds1SqlSessionTemplate(@Qualifier("ds1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
    
    
        return new SqlSessionTemplate(sqlSessionFactory);
    }
 
}

4. Configuración de la segunda fuente de datos de Mybatis ds2:

/**
 * Mybatis  第二个ds2数据源配置
 * 多数据源配置依赖数据源配置
 * @see  DataSourceConfig
 */
@Configuration
@MapperScan(basePackages ="com.web.ds2.**.dao", sqlSessionTemplateRef  = "ds2SqlSessionTemplate")
public class MybatisPlusConfig4ds2 {
    
    
 
    @Bean(name = "dataSource2")
    @ConfigurationProperties(prefix = "spring.datasource.ds2")
    public DataSource dataSource() {
    
    
        return DataSourceBuilder.create().build();
    }
 
    //ds2数据源
    @Bean("ds2SqlSessionFactory")
    public SqlSessionFactory ds2SqlSessionFactory(@Qualifier("ds2DataSource") DataSource dataSource) throws Exception {
    
    
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(dataSource);
        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().
                getResources("classpath*:com/web/ds2/**/*.xml"));
        return sqlSessionFactory.getObject();
    }
 
    //事务支持
    @Bean(name = "ds2TransactionManager")
    public DataSourceTransactionManager ds2TransactionManager(@Qualifier("ds2DataSource") DataSource dataSource) {
    
    
        return new DataSourceTransactionManager(dataSource);
    }
 
    @Bean(name = "ds2SqlSessionTemplate")
    public SqlSessionTemplate ds2SqlSessionTemplate(@Qualifier("ds2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
    
    
        return new SqlSessionTemplate(sqlSessionFactory);
    }
 
}

5. Configuración de la tercera fuente de datos de Mybatis (otro método de configuración):

Existe la gestión de transacciones DataSourceTransactionManager

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
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 org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
 
import javax.sql.DataSource;
 
@Configuration
@EnableJpaRepositories({
    
    "xxx.xxx.xx.xx.xx"})
@MapperScan(basePackages = {
    
    "xx.xx.xx.xx.xx.xx"}, sqlSessionFactoryRef = "sqlSessionFactory")
public class PrimaryDataSourceConfig {
    
    
 
    @Bean
    @ConfigurationProperties(prefix = "mybatis-plus.configuration")
    public MybatisConfiguration globalConfiguration() {
    
    
        return new MybatisConfiguration();
    }
 
    @Bean(name = "dataSource")
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    @Primary
    public DataSource dataSource() {
    
    
        return DataSourceBuilder.create().build();
    }
 
    @Bean(name = "sqlSessionFactory")
    @Primary
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
    
    
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //这里将下划线映射为驼峰的配置引入
        bean.setConfiguration(globalConfiguration());
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*.xml"));
        return bean.getObject();
    }
 
    @Bean(name = "transactionManager")
    @Primary
    public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
    
    
        return new DataSourceTransactionManager(dataSource);
    }
 
    @Bean(name = "sqlSessionTemplate")
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
    
    
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

6. Explicación del código:

  • @ConfigurationProperties(prefix = "spring.datasource.ds1"): use la configuración que comienza con spring.datasource.ds1.
  • @Qualifier: especifique el nombre de la fuente de datos, que es el mismo que el atributo de nombre en Bean, principalmente para garantizar una inyección exitosa;
  • @Primary: Declare que esta es una fuente de datos principal (la fuente de datos predeterminada), que es esencial para configuraciones de fuentes de datos múltiples.
  • @Qualifier: selecciona explícitamente el Bean entrante.

7. Precauciones:

Debido a que las rutas escaneadas de Mapper se han configurado en las dos fuentes de datos, si ha usado anotaciones de escaneo de Mapper en la clase de inicio de SpringBoot anteriormente, debe eliminarlas.

3. Prueba y uso:

Capa de servicio:

@Service
public class TestService {
    
    
 
    @Resource
    private ClusterMapper clusterMapper;
    @Resource
    private MasterMapper masterMapper;
 
    public List<HashMap<String, Object>> queryBooks() {
    
    
        return masterMapper.queryBooks(); //指定的配置类扫描的是一个包
    }
 
    public List<HashMap<String, Object>> queryOrders() {
    
    
        return clusterMapper.queryOrders(); //指定的配置类扫描的是另一个包
    }
}

Capa de controlador:

@RestController
@RequestMapping(value = "/test", method = RequestMethod.POST)
public class TestController {
    
    
    @Resource
    private TestService testService;
 
    @RequestMapping("/books")
    public List<HashMap<String, Object>> queryBooks() {
    
    
        return testService.queryBooks();
    }
 
    @RequestMapping("/orders")
    public List<HashMap<String, Object>> queryOrders() {
    
    
        return testService.queryOrders();
    }
}

5. Expansión (integrar druida)

grupo de conexiones:

De hecho, en la transformación de múltiples fuentes de datos, generalmente no usamos el método de conexión JDBC predeterminado y, a menudo, necesitamos introducir un grupo de conexiones para la optimización de la conexión; de lo contrario, es posible que encuentre registros de errores, como conexiones de fuentes de datos desconectadas.

De hecho, es muy simple para la fuente de datos cambiar la fuente de datos del grupo de conexiones, introducir directamente la dependencia del grupo de conexiones y luego reemplazar la parte de crear el origen de datos con la creación del origen de datos del grupo de conexiones.

Tomando Ali's Druid como ejemplo, primero presente la dependencia de la fuente de datos del grupo de conexiones.

importar dependencias

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid</artifactId>
</dependency>

En el archivo de configuración, agregue algunas configuraciones de Druid.

spring.datasource.datasource2.initialSize=3 # 根据自己情况设置
spring.datasource.datasource2.minIdle=3
spring.datasource.datasource2.maxActive=20

Reescriba la parte del código de creación del bean dataSource:

/**
 * Mybatis  第二个ds2数据源配置
 * 多数据源配置依赖数据源配置
 * @see  DataSourceConfig
 */
@Configuration
@MapperScan(basePackages ="com.web.ds2.**.dao", sqlSessionTemplateRef  = "ds2SqlSessionTemplate")
public class MybatisPlusConfig4ds2 {
    
    
 
    @Value("${spring.datasource.datasource2.jdbc-url}")
    private String url;
    @Value("${spring.datasource.datasource2.driver-class-name}")
    private String driverClassName;
    @Value("${spring.datasource.datasource2.username}")
    private String username;
    @Value("${spring.datasource.datasource2.password}")
    private String password;
    @Value("${spring.datasource.datasource2.initialSize}")
    private int initialSize;
    @Value("${spring.datasource.datasource2.minIdle}")
    private int minIdle;
    @Value("${spring.datasource.datasource2.maxActive}")
    private int maxActive;
 
    @Bean(name = "dataSource2")
    public DataSource dataSource() {
    
    
    	//用druid要 new DruidDataSource() 实现类,Spring Boot 默认是不注入druid这些属性值的,需要自己绑定
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setInitialSize(initialSize);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxActive(maxActive);
        return dataSource;
    }
 
    //...
 
}

Establezca la referencia de propiedad de conexión de fuente de datos, en el código de clase de configuración de fuente de datos reescrito anteriormentePresta atención a la estructura de la ruta.Configurar según sea necesario

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 连接池类型:使用druid
    type: com.alibaba.druid.pool.DruidDataSource

    #Spring Boot 默认是不注入这些属性值的,需要自己绑定
    #druid 数据源专有配置
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true

    #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
    #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
    #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

importar dependencias

<!-- 使用Druid产生的日志功能log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

Escriba la clase DruidConfig y use su función de monitoreo

package com.rui.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.HashMap;

@Configuration
public class DruidConfig {
    
    

    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druidDataSource(){
    
    
        return new DruidDataSource();
    }

    //后台监控功能 :web.xml  ServletRegistrationBean
    //因为SpringBoot 内置了servlet容器,所以没有web.xml, 替代方法ServletRegistrationBean
    //Druid 数据源具有监控的功能,并提供了一个 web 界面方便用户查看,类似安装 路由器 时,人家也提供了一个默认的 web 页面。
    @Bean
    public ServletRegistrationBean statViewServlet(){
    
    
        ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");

        HashMap<String, String> initParameter = new HashMap<>();
        //增加配置
        initParameter.put("loginUsername","admin");
        initParameter.put("loginPassword","123456");
        //允许谁可以访问
        initParameter.put("allow","");
        //deny:Druid 后台拒绝谁访问
        //initParams.put("rui", "192.168.1.20");表示禁止此ip访问
        //设置初始化参数
        bean.setInitParameters(initParameter);

        return bean;
    }

    //配置 Druid 监控 之  web 监控的 filter//WebStatFilter:用于配置Web和Druid数据源之间的管理关联监控统计
    @Bean
    public FilterRegistrationBean webStatFilter(){
    
    
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());

        HashMap<String, String> initParameter = new HashMap<>();
        //这些东西不进行统计
        initParameter.put("exclusions","*.js,*.css,/druid/*");
        //设置初始化参数
        bean.setInitParameters(initParameter);
        return bean;

    }

}

Podemos optar por visitar: http://localhost:8080/druid/login.html, y podemos ver sus potentes funciones de monitorización.

Configuración completa (se puede usar una copia)

1. Archivo de configuración del proyecto

druid: 
  mysql: 
  # mysql仅仅配置validateQuery是不行的,还要配置usePingMethod来检测连接池中的连接是否可用
  usePingMethod: false
  
# 第一数据源配置(Postgresql)
spring:
  datasource:
    # 连接池类型:使用druid
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.postgresql.Driver
    username: root
    password: 123456
    url: jdbc:postgresql://ip:端口/数据库名
    #Spring Boot 默认是不注入这些属性值的,需要自己绑定
    #druid 数据源专有配置
    initialSize: 1
    minIdle: 3
    maxActive: 20
    # 配置获取连接等待超时的时间
    maxWait: 60000
    # 连接超时不再无限重复获取
    removeAbandoned: true
    # 跳过连接超时时间
    removeAbandonedTimeout: 60
    # 关闭连接超时异常日志
    logAbandoned: true
    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    # 配置一个连接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 'X'
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
    #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
    #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,slf4j
    # 打开PSCache,并且指定每个连接上PSCache的大小(本质上就是缓存游标)
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    # 合并多个DruidDataSource的监控数据
    useGlobalDataSourceStat: true
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
  
# 第二数据源配置(mysql)
slave2:
  datasource:
    # 连接池类型:使用druid
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql://ip:端口/数据库名?useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
    #Spring Boot 默认是不注入这些属性值的,需要自己绑定
    #druid 数据源专有配置
    initialSize: 1
    minIdle: 3
    maxActive: 100
    # 配置获取连接等待超时的时间
    maxWait: 60000
    # 连接超时不再无限重复获取
    removeAbandoned: true
    # 跳过连接超时时间
    removeAbandonedTimeout: 60
    # 关闭连接超时异常日志
    logAbandoned: true
    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    # 配置一个连接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 'X'
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
    #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
    #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,slf4j
    # 打开PSCache,并且指定每个连接上PSCache的大小(本质上就是缓存游标)
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    # 合并多个DruidDataSource的监控数据
    useGlobalDataSourceStat: true
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

2. Clase de configuración

package com.xxx.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.sql.SQLException;

@Configuration
@MapperScan(basePackages = MasterDruidDBConfig.PACKAGE ,sqlSessionTemplateRef = "masterSqlSessionTemplate")
@Primary//在同样的DataSource中,首先使用被标注的DataSource
public class MasterDruidDBConfig {
    
    
	//扫描dao路径
	static final String PACKAGE = "com.xxx.*.masterdao";
	//扫描mapper路径
	static final String MAPPER_LOCATION = "classpath:mapper/*/master/*.xml";
	
    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;

    @Value("${spring.datasource.initialSize}")
    private int initialSize;

    @Value("${spring.datasource.minIdle}")
    private int minIdle;

    @Value("${spring.datasource.maxActive}")
    private int maxActive;
    //配置获取连接等待超时的时间

    @Value("${spring.datasource.maxWait}")
    private Long maxWait;
    //配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒

    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
    private Long timeBetweenEvictionRunsMillis;
    //配置一个连接在池中最小生存的时间,单位是毫秒

    @Value("${spring.datasource.minEvictableIdleTimeMillis}")
    private Long minEvictableIdleTimeMillis;

    @Value("${spring.datasource.validationQuery}")
    private String validationQuery;

    @Value("${spring.datasource.testWhileIdle}")
    private Boolean testWhileIdle;

    @Value("${spring.datasource.testOnBorrow}")
    private Boolean testOnBorrow;

    @Value("${spring.datasource.testOnReturn}")
    private Boolean testOnReturn;
    //打开PSCache,并且指定每个连接上PSCache的大小

    @Value("${spring.datasource.poolPreparedStatements}")
    private Boolean poolPreparedStatements;

    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
    private int maxPoolPreparedStatementPerConnectionSize;
    //配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙

    @Value("${spring.datasource.filters}")
    private String filters;
    //通过connectProperties属性来打开mergeSql功能;慢SQL记录

    @Value("${spring.datasource.connectionProperties}")
    private String connectionProperties;
    //合并多个DruidDataSource的监控数据
    //useGlobalDataSourceStat: true

    //连接超时不再无限重复获取
    @Value("${spring.datasource.removeAbandoned}")
    private Boolean removeAbandoned;

    //跳过连接超时时间
    @Value("${spring.datasource.removeAbandonedTimeout}")
    private int removeAbandonedTimeout;

    //关闭连接超时异常日志
    @Value("${spring.datasource.logAbandoned}")
    private Boolean logAbandoned;

    private Logger logger = LoggerFactory.getLogger(MasterDruidDBConfig.class);


    @Bean(name = "masterDataSource", initMethod = "init", destroyMethod = "close")
    //@ConfigurationProperties(prefix = "spring.datasource.master")
    @Primary//在同样的DataSource中,首先使用被标注的DataSource
    public DataSource dataSource() {
    
    
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(username);
        druidDataSource.setPassword(password);
        druidDataSource.setDriverClassName(driverClassName);
        //configuration
        druidDataSource.setInitialSize(initialSize);
        druidDataSource.setMinIdle(minIdle);
        druidDataSource.setMaxActive(maxActive);
        druidDataSource.setMaxWait(maxWait);
        druidDataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        druidDataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        druidDataSource.setValidationQuery(validationQuery);
        druidDataSource.setTestWhileIdle(testWhileIdle);
        druidDataSource.setTestOnBorrow(testOnBorrow);
        druidDataSource.setTestOnReturn(testOnReturn);
        druidDataSource.setPoolPreparedStatements(poolPreparedStatements);
        druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        try {
    
    
            druidDataSource.setFilters(filters);
        } catch (SQLException e) {
    
    
            logger.error("druid configuration initialization filter", e);
        }
        druidDataSource.setConnectionProperties(connectionProperties);
        return druidDataSource;
    }

    @Bean(name = "masterSqlSessionFactory")
    @Primary //在同样的DataSource中,首先使用被标注的DataSource
    public SqlSessionFactory sqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
    
    
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MasterDruidDBConfig.MAPPER_LOCATION));

        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        // 自动使用驼峰命名属性映射字段 userId -> user_id
        configuration.setMapUnderscoreToCamelCase(true);
        sessionFactory.setConfiguration(configuration);

        return sessionFactory.getObject();
    }

    @Bean(name = "masterTransactionManager")
    @Primary//在同样的DataSource中,首先使用被标注的DataSource
    public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
    
    
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "masterSqlSessionTemplate")
    @Primary//在同样的DataSource中,首先使用被标注的DataSource
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
    
    
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

sugerencia:
建议去使用mybatis-plus 集成 多数据源。

Para obtener más información sobre la configuración, consulte --> springboot integra la configuración de fuentes de datos múltiples de druid

Supongo que te gusta

Origin blog.csdn.net/qq_27480007/article/details/130736925
Recomendado
Clasificación