[Java] SpringBoot + Mybatis realiza una conexión de fuente de datos múltiples


Prefacio

Durante el desarrollo de un proyecto, a menudo nos encontramos con situaciones en las que necesitamos conectarnos a varias bases de datos. O el caso de múltiples bases de datos diferentes. Este artículo trata sobre la implementación de múltiples conexiones de fuentes de datos usando el marco SpringBoot + Mybatis. La base de datos usa SQL Server. ¡Ojalá te haya ayudado!


1. Importe el paquete Jar requerido (pom.xml)

        <!-- Mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <!-- Druid 数据连接池依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.11</version>
        </dependency>
        <!--SQL Server-->
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--SpringBoot 添加jdbc支持-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

2. Definir constantes de dos bases de datos.

El código es el siguiente (ejemplo):


/**
 * @author 孤巷.
 * @description
 * @date 2022/8/9 15:58
 */
public class DataBaseNameConstant {
    
    

    /**
     * HIS数据库
     */
    public static final String HIS = "his";

    /**
     * 预约挂号数据库
     */
    public static final String APPOINTMENT = "appointment";
}

3. Cree carpetas dao y mapper

(1) Distinga dos fuentes de datos en el directorio de la carpeta dao
Insertar descripción de la imagen aquí
(2) Distinga dos fuentes de datos en la carpeta del asignador

Insertar descripción de la imagen aquí

4. Crear una clase de configuración de fuente de datos

Cree una fuente de datos de carpeta y cree cinco nuevas clases de configuración en ella.
Insertar descripción de la imagen aquí
El código específico es el siguiente:
(1) Fuente de datos

import java.lang.annotation.*;

/**
 * mybatis自定义注解,用来声明数据源
 *
 * @author wcs
 */
@Target({
    
    ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
    
    
    String value();
}

(2)Aspecto de fuente de datos

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * mybatis切面,用来切换数据源
 *
 * @author wcs
 */
@Aspect
@Component
@Slf4j
public class DataSourceAspect {
    
    

    @Pointcut("execution(* com.example.web.dao.*.*.*(..))")
    public void dataSourcePointCut() {
    
    

    }

    @Before("dataSourcePointCut()")
    public void before(JoinPoint point) {
    
    
        Object target = point.getTarget();
        DataSource dataSource = target.getClass().getInterfaces()[0].getAnnotation(DataSource.class);
        if (dataSource != null) {
    
    
            String key = dataSource.value();
            log.info("当前运行的数据源为 == {}",key);
            DynamicDataSourceHolder.setDataSource(key);
        }
    }
}

(3)Configuración de fuente de datos

import com.alibaba.druid.pool.DruidDataSource;
import com.example.web.constant.DataBaseNameConstant;
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;

/**
 * @author wcs
 * @description 多数据源配置
 * @date 2021/3/13 11:44
 */
@Configuration
public class DatasourceConfig {
    
    

    @Bean(name = DataBaseNameConstant.HIS)
    @ConfigurationProperties(prefix = "spring.datasource.druid.his")
    public DataSource hisDruid() {
    
    
        return new DruidDataSource();
    }

    @Bean(name = DataBaseNameConstant.APPOINTMENT)
    @ConfigurationProperties(prefix = "spring.datasource.druid.appointemnt")
    public DataSource appointemntDruid() {
    
    
        return new DruidDataSource();
    }



    @Bean
    @Primary
    public DynamicDataSource dataSource() {
    
    
        Map<String, DataSource> targetDataSources = new HashMap<>(4);
        targetDataSources.put(DataBaseNameConstant.HIS, hisDruid());
        targetDataSources.put(DataBaseNameConstant.APPOINTMENT, appointemntDruid());
        return new DynamicDataSource(targetDataSources.get(DataBaseNameConstant.HIS), targetDataSources);
    }
}

(4)Fuente de datos dinámica

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

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

/**
 * mybatis自定义数据源
 *
 * @author wcs
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
    
    

    public DynamicDataSource(DataSource defaultTargetDataSource, Map<String, DataSource> targetDataSources) {
    
    
        super.setDefaultTargetDataSource(defaultTargetDataSource);
        super.setTargetDataSources(new HashMap<>(targetDataSources));
        super.afterPropertiesSet();
    }

    @Override
    protected Object determineCurrentLookupKey() {
    
    
        return DynamicDataSourceHolder.getDataSouce();
    }

}

(5)Soporte de fuente de datos dinámicos

/**
 * mybatis自定义数据源管理器
 *
 * @author wcs
 */
public class DynamicDataSourceHolder {
    
    
    public static final ThreadLocal<String> holder = new ThreadLocal<String>();

    public static void setDataSource(String name) {
    
    
        holder.set(name);
    }

    public static String getDataSouce() {
    
    
        return holder.get();
    }
}

5. Defina el archivo de la aplicación.

提示:本文中还会用到lombok以及Druid,这两个jar包在网上都能找到
(1)
El código del contenido del archivo Application.yml es el siguiente:

#开发环境配置
server:
  port: 9803
spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB
  datasource:
    druid:
      his:
        url:  jdbc:sqlserver://127.0.0.1:1433;databaseName=test;
        driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
        username: test
        password: test
        initial-size: 5 #初始化时建立物理连接的个数。
        max-active: 20  #最大连接池数量
        min-idle: 5     #最小连接池数量
        max-wait: 3000  #获取连接时最大等待时间,单位毫秒
        pool-prepared-statements: false #是否缓存preparedStatement,也就是PSCache,PSCache对支持游标的数据库性能提升巨大,比如说oracle,在mysql下建议关闭。
        #要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在OraclePSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
        max-open-prepared-statements: 100
        time-between-eviction-runs-millis: 60000 #配置检测可以关闭的空闲连接间隔时间
        min-evictable-idle-time-millis: 300000 # 配置连接在池中的最小生存时间
        max-evictable-idle-time-millis: 400000
        filters: stat,slf4j #监控统计的stat,以及防sql注入的wall
        web-stat-filter:
          enabled: true
        validation-query: SELECT 1
        # StatViewServlet配置,说明请参考Druid Wiki,配置_StatViewServlet配置
        #是否启用StatViewServlet(监控页面)默认值为false(考虑到安全问题默认并未启动,如需启用建议设置密码或白名单以保障安全)
        stat-view-servlet:
          enabled: true       #是否启用StatViewServlet默认值true
          url-pattern: /druid/* #访问路径为/druid时,跳转到StatViewServlet
          reset-enable: true #是否能够重置数据
          login-username: whxx
          login-password: whxx666.
          allow: localhost
        test-on-borrow: false
        test-on-return: false
        test-while-idle: true
        max-pool-prepared-statement-per-connection-size: 20
        filter:
          stat:
            log-slow-sql: true
            slow-sql-millis: 2000
          slf4j:
            enabled: true
            result-set-log-enabled: false
            statement-create-after-log-enabled: false
            statement-close-after-log-enabled: false
            result-set-open-after-log-enabled: false
            result-set-close-after-log-enabled: false
      appointemnt:
        url: jdbc:sqlserver://127.0.0.1:1433;databaseName=test1;
        driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
        username: test1
        password: test1
        initial-size: 5 #初始化时建立物理连接的个数。
        max-active: 20  #最大连接池数量
        min-idle: 5     #最小连接池数量
        max-wait: 3000  #获取连接时最大等待时间,单位毫秒
        pool-prepared-statements: false #是否缓存preparedStatement,也就是PSCache,PSCache对支持游标的数据库性能提升巨大,比如说oracle,在mysql下建议关闭。
        #要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
        max-open-prepared-statements: 100
        time-between-eviction-runs-millis: 60000 #配置检测可以关闭的空闲连接间隔时间
        min-evictable-idle-time-millis: 300000 # 配置连接在池中的最小生存时间
        max-evictable-idle-time-millis: 400000
        filters: stat,slf4j #监控统计的stat,以及防sql注入的wall
        web-stat-filter:
          enabled: true
        validation-query: SELECT 1
        # StatViewServlet配置,说明请参考Druid Wiki,配置_StatViewServlet配置
        #是否启用StatViewServlet(监控页面)默认值为false(考虑到安全问题默认并未启动,如需启用建议设置密码或白名单以保障安全)
        stat-view-servlet:
          enabled: true       #是否启用StatViewServlet默认值true
          url-pattern: /druid/* #访问路径为/druid时,跳转到StatViewServlet
          reset-enable: true #是否能够重置数据
          login-username: whxx
          login-password: whxx666.
          allow: localhost
        test-on-borrow: false
        test-on-return: false
        test-while-idle: true
        max-pool-prepared-statement-per-connection-size: 20
        filter:
          stat:
            log-slow-sql: true
            slow-sql-millis: 2000
          slf4j:
            enabled: true
            result-set-log-enabled: false
            statement-create-after-log-enabled: false
            statement-close-after-log-enabled: false
            result-set-open-after-log-enabled: false
            result-set-close-after-log-enabled: false
mybatis:
  mapper-locations: classpath:mapper/*/*.xml #xml文件位置
  type-aliases-package: com.example.web.bean
  configuration:
    map-underscore-to-camel-case: true
    call-setters-on-nulls: true #处理数据为null时键值对不存在



Resumir

El código de esta publicación se ha publicado y puede hacer otras preguntas en el área de comentarios a continuación, ¡y el blogger le dará una respuesta a tiempo! ¡Gracias por su atención!

Supongo que te gusta

Origin blog.csdn.net/qq_42666609/article/details/130221136
Recomendado
Clasificación