Der Fehler, dass Springboot bei der Integration mehrerer Datenquellen + Mybatis-Plus nicht paginieren kann

1. Springboot integriert mehrere Datenquellen

1.1 Einführung in Abhängigkeiten

<dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>

1.2 Konfigurieren Sie die YML-Datei

Achten Sie unbedingt auf die Namen der verschiedenen Datenquellen unter den Kommentaren, da der nächste Schritt darin besteht, die Konfiguration der YML-Datei manuell und nicht automatisch abzurufen. Da diese beiden Datenbanken möglicherweise nicht gleichzeitig verwendet werden, habe ich den aktivierten Schalter hinzugefügt. Wenn er wahr ist, wird die Datenbankkonfiguration geladen

spring:
  #mysql数据源
  mysqldb:
    enabled: false
    driver-class-name: com.mysql.cj.jdbc.Driver
    password: root
    url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8&useUnicode=true&serverTimezone=Asia/Shanghai&allowMultiQueries=true&useAffectedRows=true&useSSL=false
    username: root
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    filters: stat,wall,log4j
    initialSize: 5
    maxActive: 20
    maxPoolPreparedStatementPerConnectionSize: 20
    maxWait: 60000
    minEvictableIdleTimeMillis: 300000
    minIdle: 5
    poolPreparedStatements: true
    testOnBorrow: false
    testOnReturn: false
    testWhileIdle: true
    timeBetweenEvictionRunsMillis: 60000
    validationQuery: SELECT 1 FROM DUAL
  #psql数据源
  psqldb:
    enabled: true
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://127.0.0.1:9543/test
    username: postgres
    password: postgres
    # 初始化大小,最小,最大
    initialSize: 1
    minIdle: 3
    maxActive: 200
    # 配置获取连接等待超时的时间
    maxWait: 60000
    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    # 配置一个连接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 40000
    validationQuery: select 'x'
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false

1.3 Erstellen Sie ein Konfigurationspaket. Solange SpringBoot es scannt, müssen der Startklasse keine besonderen Kommentare hinzugefügt werden

Verwandte Konfiguration von MySQL

import lombok.Data;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.Serializable;


@Component
@Data
@ConfigurationProperties(prefix = "spring.mysqldb")
public class MysqlDataSourceProperties implements Serializable {
    
    

    private String driverClassName;
    private String url;
    private String username;
    private String password;
    private String connectionProperties;
    private String filters;
    private Integer initialSize;
    private Integer maxActive;
    private Integer maxPoolPreparedStatementPerConnectionSize;
    private Integer maxWait;
    private Integer minEvictableIdleTimeMillis;
    private Integer minIdle;
    private boolean poolPreparedStatements;
    private boolean testOnBorrow;
    private boolean testOnReturn;
    private boolean testWhileIdle;
    private Integer timeBetweenEvictionRunsMillis;
    private String validationQuery;
    private boolean enabled;

}

MySQL laden


import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.autoconfigure.SpringBootVFS;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
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 org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

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

@Configuration
## ConditionalOnProperty指定enabled开启时,才会加载该数据库相关信息
@ConditionalOnProperty(prefix = "spring.mysqldb", name = "enabled", havingValue = "true")
@MapperScan(basePackages = "com.koal.ipsec.mapper", sqlSessionFactoryRef = "mysqlSqlSessionFactory")
public class MysqlDataSourceConfig {
    
    

    @Autowired
    private MysqlDataSourceProperties mysqlDataSourceProperties;

    @Bean(name = "mysqlDataSource")
    public DataSource dataSource() {
    
    
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(mysqlDataSourceProperties.getDriverClassName());
        dataSource.setUrl(mysqlDataSourceProperties.getUrl());
        dataSource.setUsername(mysqlDataSourceProperties.getUsername());
        dataSource.setPassword(mysqlDataSourceProperties.getPassword());
        dataSource.setInitialSize(mysqlDataSourceProperties.getInitialSize());
        dataSource.setMinIdle(mysqlDataSourceProperties.getMinIdle());
        dataSource.setMaxActive(mysqlDataSourceProperties.getMaxActive());
        return dataSource;
    }

    @Bean
    public PaginationInterceptor paginationInterceptor() {
    
    
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setDialectType(DbType.MYSQL.getDb());
        return paginationInterceptor;
    }

    @Bean(name = "mysqlSqlSessionFactory")
    @Primary
    public SqlSessionFactory sqlSessionFactory(@Qualifier("mysqlDataSource") DataSource dataSource) throws Exception {
    
    
      ##注意: Mybatis plus分页插件配置必须使用MybatisSqlSessionFactoryBean ,否则分页失效
      ## MybatisSqlSessionFactoryBean 是为了解决扫包的时候无法扫描mybatis-plus的mapper的问题。
        final MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
       ## 重点
        MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
        mybatisSqlSessionFactoryBean.setConfiguration(mybatisConfiguration);
        mybatisSqlSessionFactoryBean.setDataSource(dataSource);
        mybatisSqlSessionFactoryBean.setPlugins(new Interceptor[]{
    
    paginationInterceptor()});
        ## 指定enum类的扫描
        mybatisSqlSessionFactoryBean.setTypeEnumsPackage("com.test.constant");
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resourcePatternResolver.getResources("classpath*:mapper/*Mapper.xml");
        mybatisSqlSessionFactoryBean.setMapperLocations(resources);
        return mybatisSqlSessionFactoryBean.getObject();
    }
    @Bean(name = "mysqlSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("mysqlSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
    
    
        return new SqlSessionTemplate(sqlSessionFactory);
    }
    @Bean(name = "mysqlTransactionManager")
    public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("mysqlDataSource") DataSource dataSource) {
    
    
        return new DataSourceTransactionManager(dataSource);
    }

}

psql-bezogene Konfiguration


import lombok.Data;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.Serializable;

@Component
@Data
@ConfigurationProperties(prefix = "spring.psqldb")
public class PsqlDataSourceProperties implements Serializable {
    
    

    private String driverClassName;
    private String url;
    private String username;
    private String password;
    private Integer initialSize;
    private Integer maxActive;
    private Integer maxWait;
    private Integer minIdle;
    private Integer timeBetweenEvictionRunsMillis;
    private Integer minEvictableIdleTimeMillis;
    private String validationQuery;
    private boolean testOnBorrow;
    private boolean testOnReturn;
    private boolean testWhileIdle;

}


import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@ConditionalOnProperty(prefix = "spring.psqldb", name = "enabled", havingValue = "true")
@MapperScan(basePackages = "com.koal.ipsec.mapper", sqlSessionFactoryRef = "psqlSqlSessionFactory")
public class PsqlDataSourceConfig {
    
    

    @Autowired
    private PsqlDataSourceProperties psqlDataSourceProperties;

    @Bean(name = "psqlDataSource")
    public DataSource dataSource() {
    
    
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(psqlDataSourceProperties.getDriverClassName());
        dataSource.setUrl(psqlDataSourceProperties.getUrl());
        dataSource.setUsername(psqlDataSourceProperties.getUsername());
        dataSource.setPassword(psqlDataSourceProperties.getPassword());
        dataSource.setInitialSize(psqlDataSourceProperties.getInitialSize());
        dataSource.setMinIdle(psqlDataSourceProperties.getMinIdle());
        dataSource.setMaxActive(psqlDataSourceProperties.getMaxActive());
        return dataSource;
    }

    @Bean
    public PaginationInterceptor paginationInterceptor() {
    
    
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setDialectType(DbType.POSTGRE_SQL.getDb());
        return paginationInterceptor;
    }

    @Bean(name = "psqlSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("psqlDataSource") DataSource dataSource) throws Exception {
    
    
        final MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
        mybatisSqlSessionFactoryBean.setConfiguration(mybatisConfiguration);
        mybatisSqlSessionFactoryBean.setDataSource(dataSource);
        mybatisSqlSessionFactoryBean.setPlugins(new Interceptor[]{
    
    paginationInterceptor()});
       // mybatisSqlSessionFactoryBean.setPlugins(new Interceptor[]{
    
    psqlMybatisPlusConfig.paginationInterceptor()});
        mybatisSqlSessionFactoryBean.setTypeEnumsPackage("com.koal.ipsec.constant");
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resourcePatternResolver.getResources("classpath*:mapper/*Mapper.xml");
        mybatisSqlSessionFactoryBean.setMapperLocations(resources);
        return mybatisSqlSessionFactoryBean.getObject();
    }
    @Bean(name = "psqlSqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("psqlSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
    
    
        return new SqlSessionTemplate(sqlSessionFactory);
    }
    @Bean(name = "psqlTransactionManager")
    public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("psqlDataSource") DataSource dataSource) {
    
    
        return new DataSourceTransactionManager(dataSource);
    }



}

1. MapperScanIm Inneren basePackageswird der Speicherort der von MyBatis bereitgestellten Mapper-Schnittstelle gescannt. Das sqlSessionTemplateRef kann nach Belieben benannt werden und hat keinen Einfluss auf die folgenden Anmerkungen. Beachten Sie jedoch, dass es sich von den Namen der anderen Konfigurationsklassen unterscheiden sollte.

2. Vor jeder Methode der MysqlDataSourceConfig-Klasse befinden sich Anmerkungen @Primary, und die Methode der PsqlDataSourceConfig-Klasse wird zu @Qualifier (der Name hier ist auch willkürlich, solange diese Klassen unterschiedlich sind). Dies soll verhindern, dass SpringBoot automatisch zusammengebaut wird . Mehrere Datenquellen, Sie wissen nicht, welche Sie verwenden sollen, und melden beim Start einen Fehler. Wenn mehr als zwei Datenquellen vorhanden sind, verwenden Sie die Annotation @Qualifier wie PsqlDataSourceConfig für die übrigen Methoden der Konfigurationsklasse.

2. Beheben Sie den Fehler, dass mybatis-plus bei mehreren Datenquellen keine Paginierung durchführen kann

Problem:
Wenn das Projekt eine einzelne Datenquelle konfiguriert, funktioniert das mybatis-plus-Paging-Plugin normal. Bei der Konfiguration mehrerer Datenquellen schlägt das mybatis-plus-Paging-Plugin fehl.

2.1 Mybatis-plus-Paging-Plugin injizieren

   @Bean
    public PaginationInterceptor paginationInterceptor() {
    
    
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setDialectType(DbType.POSTGRE_SQL.getDb());
        return paginationInterceptor;
    }

2.2 Konfiguration unter mehreren Datenquellen

 @Bean(name = "mysqlSqlSessionFactory")
    @Primary
    public SqlSessionFactory sqlSessionFactory(@Qualifier("mysqlDataSource") DataSource dataSource) throws Exception {
    
    
      ##注意: Mybatis plus分页插件配置必须使用MybatisSqlSessionFactoryBean ,否则分页失效
      ## MybatisSqlSessionFactoryBean 是为了解决扫包的时候无法扫描mybatis-plus的mapper的问题。
        final MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
       ## 重点
        MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
        mybatisSqlSessionFactoryBean.setConfiguration(mybatisConfiguration);
        mybatisSqlSessionFactoryBean.setDataSource(dataSource);
        mybatisSqlSessionFactoryBean.setPlugins(new Interceptor[]{
    
    paginationInterceptor()});
        ## 指定enum类的扫描
        mybatisSqlSessionFactoryBean.setTypeEnumsPackage("com.test.constant");
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resourcePatternResolver.getResources("classpath*:mapper/*Mapper.xml");
        mybatisSqlSessionFactoryBean.setMapperLocations(resources);
        return mybatisSqlSessionFactoryBean.getObject();
    }

Die Konfiguration mehrerer Datenquellen muss per Code implementiert werden, anstatt die Standardeigenschaftenkonfiguration zu verwenden. Hier verwende ich
MybatisSqlSessionFactoryBean, um SqlSessionFactory zu konfigurieren, und MybatisSqlSessionFactoryBean verfügt lediglich über eine Methode namens
setPlugins:, die zum Konfigurieren von Plugins verwendet wird.

Mit MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean(); soll das Problem gelöst werden, dass der Mapper von mybatis-plus beim Scannen von Paketen nicht gescannt werden kann.

Acho que você gosta

Origin blog.csdn.net/sunrj_niu/article/details/124469758
Recomendado
Clasificación