springboot和mybatis 配置多數據源 數據庫連接池之Hikari源碼解析

 主數據源(由於代碼沒有辦法複製的原因,下面圖片和文字不一致)

 

 

package com.xxxx.config;
 
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
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;
 
 
/**
 * @program: test
 * @description:
 * @author: chenzhian
 * @create: 2021-10-13 20:31:54
 * @version: 1.0
 **/
@Configuration
// 掃描 Mapper 接口並容器管理
// @MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig {
 
 
    // 精確到 master 目錄,以便跟其他數據源隔離
    static final String PACKAGE = "com.xxx.masterdao";
    static final String MAPPER_LOCATION = "classpath:mapper/master/*.xml";
 

 
    @Bean(name = "masterDataSource")
    @Primary
    public DataSource masterDataSource() {
        return new HikariDataSource();
    }
 
    @Bean(name = "masterTransactionManager")
    @Primary
    public DataSourceTransactionManager masterTransactionManager() {
        return new DataSourceTransactionManager(masterDataSource());
    }
 
    @Bean(name = "masterSqlSessionFactory")
    @Primary
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource)
            throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(masterDataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(MasterDataSourceConfig.MAPPER_LOCATION));
        return sessionFactory.getObject();
    }


/*
可以另外手動指定目錄
*/
@Bean(name="masterMapperScannerConfigurer")
public MapperScannerConfigurer masterMapperScannerConfigurer(){
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setSqlSessionFactoryBeanName("secondSqlSessionFactory");
configurer.setBasePackage(PACKAGE);
return configurer;
}


 
}

 

 

 

 第二個數據源(由於代碼沒有辦法複製的原因,下面圖片和文字不一致)

 

 

package com.xxxx.config;
 
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
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;
 
 
/**
 * @program: test
 * @description:
 * @author: chenzhian
 * @create: 2021-10-13 20:31:54
 * @version: 1.0
 **/
@Configuration
// 掃描 Mapper 接口並容器管理
// @MapperScan(basePackages = secondDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "secondSqlSessionFactory")
public class SecondDataSourceConfig {
 
 
    // 精確到 second 目錄,以便跟其他數據源隔離
    static final String PACKAGE = "com.xxx.seconddao";
    static final String MAPPER_LOCATION = "classpath:mapper/second/*.xml";
 

 
    @Bean(name = "secondDataSource")
    @Primary
    public DataSource secondDataSource() {
        return new HikariDataSource();
    }
 
    @Bean(name = "secondTransactionManager")
    @Primary
    public DataSourceTransactionManager secondTransactionManager() {
        return new DataSourceTransactionManager(secondDataSource());
    }
 
    @Bean(name = "secondSqlSessionFactory")
    @Primary
    public SqlSessionFactory secondSqlSessionFactory(@Qualifier("secondDataSource") DataSource secondDataSource)
            throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(secondDataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(secondDataSourceConfig.MAPPER_LOCATION));
        return sessionFactory.getObject();
    }


  


/*
可以另外手動指定目錄
*/
@Bean(name="secondMapperScannerConfigurer")
public MapperScannerConfigurer crwalerMapperScannerConfigurer(){
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setSqlSessionFactoryBeanName("secondSqlSessionFactory");
configurer.setBasePackage(PACKAGE);
return configurer;
}


 
}

 

 

 

application.yml的配置

 

 

# master 數據源配置
master:
  datasource:
    url: jdbc:mysql://localhost:33306/mastertest?serverTimezone=GMT&useUnicode=true&characterEncoding=utf8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: sa
    password: sa!@123
    type: com.zaxxer.hikari.HikariDataSource
    minimum-idle: 5   #最小空閒連接數量
    maximum-pool-size: 50   #連接池中最大連接數
    max-lifetime: 180000  #連接最長生命週期,當連接存活時間達到30分鐘之後會被關閉作退休處理
    idle-timeout: 30000   # 連接允許最長空閒時間,如果連接空閒時間超過1分鐘,則會被關閉
    connection-timeout: 30000  客戶端創建連接等待超時時間,如果30秒內沒有獲取連接則拋異常,不再繼續等待

# second 數據源配置
second:
  datasource:
    url: jdbc:mysql://localhost:33306/sencondtest?serverTimezone=GMT&useUnicode=true&characterEncoding=utf8
    username: root
    password: 1q2w#E4r
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.zaxxer.hikari.HikariDataSource
    minimum-idle: 5   #最小空閒連接數量
    maximum-pool-size: 50   #連接池中最大連接數
    max-lifetime: 180000  #連接最長生命週期,當連接存活時間達到30分鐘之後會被關閉作退休處理
    idle-timeout: 30000   # 連接允許最長空閒時間,如果連接空閒時間超過1分鐘,則會被關閉
    connection-timeout: 30000  客戶端創建連接等待超時時間,如果30秒內沒有獲取連接則拋異常,不再繼續等待

 

更多Hikari的配置請看最後的來源

 

Hikari是SpringBoot2.0以後默認使用的數據庫連接池,如果是老的話可能會使用到Druid 用來做數據庫連接池,下面是對兩個的瞭解介紹

SpringBoot基礎篇(二)連接池hikari和druid

 

HiKariCP和Druid對比使用整理自測

 

mybatis 配置 多個數據源 org.apache.ibatis.binding.BindingException Vakud bound statement (not found)

原因是沒有配置@MapperScan ,因爲我這裏是多個目錄,所以也要配置多個,在Application的啓動上面加

@MapperScan(value{"com.xxxx","com.aaaa"})

如果上面有用到MapperScannerConfigurer 就不需要這個了。

 

 

The bean 'xxxService' could not be injected as a 'com.xxxxImpl' because it is a JDK dynamic proxy that implements:
com.xxxxService

Action:

Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching.

原因居然是因爲用到是@Resouce 來直接調用ServiceImpl,造成程序加載的時候還沒有Service的Impl實現類,讓程序加載的時候找不到這個類

解決方案

改成調用Service 接口,另外把@Resouce 改成 @Autowired 就可以了。

 

 

 

 

資料整理來源

 

SpringBoot和Mybatis配置多數據源連接多個數據庫

 

數據庫連接池之Hikari源碼解析

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章