springboot3.2+多数据源+hikari连接池

环境

  • springboot3
  • hikari5

yml配置

spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    zb:
      driver-class-name: dm.jdbc.driver.DmDriver
      #jdbc-url: jdbc:dm://127.0.0.1:5432/ZB 
      url: jdbc:dm://127.0.0.1:5432/ZB
      username: admin
      password: xxxxxx
      hikari:
        pool-name: HikariPool-ZB
        connection-timeout: 10000  #连接超时时间
        validation-timeout: 3000  #
        idle-timeout: 60000 #一个连接idle状态的最大时长(毫秒),超时则被释放,默认:10分钟
        login-timeout: 5
        max-lifetime: 60000 #连接空闲后的最大存活时间
        maximum-pool-size: 15  #最大连接数
        minimum-idle: 6   #最小连接数
        auto-commit: true
        connection-test-query: select 1
    ty:
      driver-class-name: dm.jdbc.driver.DmDriver
      #jdbc-url: jdbc:dm://127.0.0.1:5432/TY
      url: jdbc:dm://127.0.0.1:5432/TY
      username: admin
      password: xxxxxx
      hikari:
        pool-name: HikariPool-TY
        connection-timeout: 10000  #连接超时时间
        validation-timeout: 3000  #
        idle-timeout: 60000 #一个连接idle状态的最大时长(毫秒),超时则被释放,默认:10分钟
        login-timeout: 5
        max-lifetime: 60000 #连接空闲后的最大存活时间
        maximum-pool-size: 15  #最大连接数
        minimum-idle: 5   #最小连接数
        auto-commit: true
        connection-test-query: select 1

数据源配置

有两个数据源配置,所以写了2个config,分开写看着比较清晰,其中zb为主链接
需要注意几点:

  • 不使用DataSourceProperties对象
    • 创建的HikariDataSource时,yml中要用spring.datasourc.xx下边要用jdbc-url属性,否则会报错;
    • 使用DataSourceProperties对象创建的HikariDataSource时,要用jdbc-url属性;
  • 指定hikari.pool-name
    • 需要创建个DataSourceProperties bean,基于这个对象再创建HikariDataSource,此时连接池配置生效;

DbZbConfiguration.java

import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.log4j.Log4j2;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
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.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration()
@Log4j2
public class DbZbConfiguration {
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ZB库
    @Bean("zbDataSourceProperties")
    @ConfigurationProperties("spring.datasource.zb")
    @Primary
    public DataSourceProperties zbDataSourceProperties() {
        return new DataSourceProperties();
    }
    @Bean(name = "zbDataSource")
    @ConfigurationProperties("spring.datasource.zb.hikari")
    @Primary
    public HikariDataSource dataSource() {
        //HikariDataSource dataSource = (HikariDataSource) DataSourceBuilder.create().build();
        HikariDataSource dataSource = zbDataSourceProperties()
                .initializeDataSourceBuilder()
                .type(HikariDataSource.class)
                .build();
        return dataSource;
    }
    @Bean(name="zbTransactionManager")
    @Primary
    DataSourceTransactionManager transactionManager(@Qualifier("zbDataSource") DataSource datasource) {
        DataSourceTransactionManager txm  = new DataSourceTransactionManager(datasource);
        return txm;
    }
    @Bean(name = "zbSqlSessionFactory")
    @Primary
    public SqlSessionFactory sqlSessionFactory(@Qualifier("zbDataSource") DataSource dataSource) throws Exception {
        //解决: Invalid bound statement (not found) 异常
//        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
//        sessionFactory.setDataSource(datasource);
//        return sessionFactory.getObject();
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        //SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //设置mybatis的xml所在位置
        Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*Mapper.xml");
        bean.setMapperLocations(resources);
        SqlSessionFactory factory = bean.getObject();
        log.info(">>> ZB数据源连接字符串: {}", ((HikariDataSource) dataSource).getJdbcUrl());
        return factory;
    }

    @Bean(name = "zbSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("zbSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
        return sqlSessionTemplate;
    }
}

DbTyConfiguration.java


import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.log4j.Log4j;
import lombok.extern.log4j.Log4j2;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
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.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@Log4j2
public class DbTyConfiguration {

    @Bean("tyDataSourceProperties")
    @ConfigurationProperties("spring.datasource.ty")
    @Primary
    public DataSourceProperties tyDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean(name = "tyDataSource")
    @ConfigurationProperties("spring.datasource.ty.hikari")
    public HikariDataSource tyDataSource() {
        //HikariDataSource dataSource = (HikariDataSource) DataSourceBuilder.create().build();
        HikariDataSource dataSource = tyDataSourceProperties()
                .initializeDataSourceBuilder()
                .type(HikariDataSource.class)
                .build();
        return dataSource;
    }
    @Bean(name="tyTransactionManager")
    DataSourceTransactionManager tyTransactionManager(@Qualifier("tyDataSource") DataSource datasource) {
        DataSourceTransactionManager txm  = new DataSourceTransactionManager(datasource);
        return txm;
    }
    @Bean(name = "tySqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("tyDataSource") DataSource dataSource) throws Exception {
        //解决: Invalid bound statement (not found) 异常
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        //SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //设置mybatis的xml所在位置
        Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*Mapper.xml");
        bean.setMapperLocations(resources);
        SqlSessionFactory factory = bean.getObject();
        log.info(">>> TY数据源连接字符串: {}", ((HikariDataSource) dataSource).getJdbcUrl());
        return factory;
    }

    @Bean(name = "tySqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("tySqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
        return sqlSessionTemplate;
    }
}

多数源的使用

这种配置可以按需对mapper进行初始化,主要解决的是相同表结构不同数据库之间,公用相同mapper的问题。
避免mapper实例重复,多个mapper bean可以使用下面的方式注入:

    @Bean("secondMapper")
    public SecondMapper getMapper(){
        var tySqlSessionFactory = (SqlSessionFactory)SpringUtil.getBean("tySqlSessionFactory");
        var session = tySqlSessionFactory.openSession();
        var mapper = session.getMapper(SecondMapper.class);
        return mapper;
    }

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐