前言
在日常开发中,由于项目结构不断复杂,特别是多系统对接时,经常会遇到要读取其他数据库的情况,这个时候就需要我们去配置多个数据源来满足自己的需求。
配置文件
本文章中采用的yml配置文件,配置如下,在yml中定义两个数据源。
代码
在项目中新建两个配置类,读取yml文件中的数据源配置信息,将其注入到spring容器中。(注意:一定要指定一个默认数据源),否则在启动项目时会报错。代码如下:
package com.hentor.damaiservice.configuration;
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.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.core.JdbcTemplate;
import javax.sql.DataSource;
import java.sql.SQLException;
/**
* @version 1.0.0
* @description: 数据源驱动类型
* @author: Zev.Zhang
* @date: 2019/12/17 2:43 下午
*/
@Configuration
@MapperScan(basePackages = "com.hentor.damaiservice.dao", sqlSessionFactoryRef = "primarySqlSessionFactory")
public class DruidDataSourceConfig {
@Value("${spring.datasource.primary.driver-class-name}")
private String driver;
/**
* 连接地址
*/
@Value("${spring.datasource.primary.url}")
private String url;
/**
* 用户名
*/
@Value("${spring.datasource.primary.username}")
private String username;
/**
* 密码
*/
@Value("${spring.datasource.primary.password}")
private String password;
/**
* 初始连接
*/
@Value("${spring.datasource.primary.initial-size}")
private int initialSize;
/**
* 最大连接
*/
@Value("${spring.datasource.primary.max-total}")
private int maxActive;
/**
* 最小连接
*/
@Value("${spring.datasource.primary.min-idle}")
private int minIdle;
/**
* 最大超时等待时间
*/
@Value("${spring.datasource.primary.max-wait-millis}")
private Long maxWaitMillis;
/**
* 配置Druid数据源
* @return
* @throws SQLException
*/
@Bean(name="primaryDataSource")
@Primary
public DataSource dataSource() throws SQLException{
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
//配置最大连接
dataSource.setMaxActive(maxActive);
//配置初始连接
dataSource.setInitialSize(initialSize);
//配置最小连接
dataSource.setMinIdle(minIdle);
//连接等待超时时间
dataSource.setMaxWait(maxWaitMillis);
return dataSource;
}
@Bean(name = "primarySqlSessionFactory")
// 表示这个数据源是默认数据源
@Primary
public SqlSessionFactory test1SqlSessionFactory(@Qualifier("primaryDataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
bean.setMapperLocations(
// 设置mybatis的xml所在位置
new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/primary/*.xml"));
return bean.getObject();
}
@Bean("primarySqlSessionTemplate")
// 表示这个数据源是默认数据源
@Primary
public SqlSessionTemplate primarySqlsessiontemplate(
@Qualifier("primarySqlSessionFactory") SqlSessionFactory sessionfactory) {
return new SqlSessionTemplate(sessionfactory);
}
}
@MapperScan注解,指定该数据源应该扫描的包,其中basePackages参数指定的是需要被扫描的接口类,后面配置的datasource、SqlSessionTemplate、SqlSessionFactory都需要增加@Primary注解,表示优先使用该注解下的bean。
第二个数据源配置类的写法基本与之一致,只是少了@Primary注解,记得数据源1和数据源2的接口包和存放xml的包需要分开。
package com.hentor.damaiservice.configuration;
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.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 javax.sql.DataSource;
import java.sql.SQLException;
/**
* @version 1.0.0
* @description: oracle数据源驱动类型
* @author: Zev.Zhang
* @date: 2019/12/17 2:43 下午
*/
@Configuration
@MapperScan(basePackages = "com.hentor.damaiservice.secondDao", sqlSessionFactoryRef = "secondarySqlSessionFactory")
public class SecondaryDruidDataSourceConfig {
@Value("${spring.datasource.secondary.driver-class-name}")
private String driver;
/**
* 连接地址
*/
@Value("${spring.datasource.secondary.url}")
private String url;
/**
* 用户名
*/
@Value("${spring.datasource.secondary.username}")
private String username;
/**
* 密码
*/
@Value("${spring.datasource.secondary.password}")
private String password;
/**
* 初始连接
*/
@Value("${spring.datasource.secondary.initial-size}")
private int initialSize;
/**
* 最大连接
*/
@Value("${spring.datasource.secondary.max-total}")
private int maxActive;
/**
* 最小连接
*/
@Value("${spring.datasource.secondary.min-idle}")
private int minIdle;
/**
* 最大超时等待时间
*/
@Value("${spring.datasource.secondary.max-wait-millis}")
private Long maxWaitMillis;
/**
* 配置Druid数据源
* @return
* @throws SQLException
*/
@Bean(name="secondaryDataSource")
public DataSource dataSource() throws SQLException{
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
//配置最大连接
dataSource.setMaxActive(maxActive);
//配置初始连接
dataSource.setInitialSize(initialSize);
//配置最小连接
dataSource.setMinIdle(minIdle);
//连接等待超时时间
dataSource.setMaxWait(maxWaitMillis);
//一个连接最小生存时间
dataSource.setMinEvictableIdleTimeMillis(300000);
//连接等待超时时间 单位为毫秒 缺省启用公平锁,
//并发效率会有所下降, 如果需要可以通过配置useUnfairLock属性为true使用非公平锁
dataSource.setUseUnfairLock(true);
//用来检测是否有效的sql
dataSource.setValidationQuery("SELECT 1 FROM DUAL");
dataSource.setTestWhileIdle(true);
//申请连接时执行validationQuery检测连接是否有效,配置为true会降低性能
dataSource.setTestOnBorrow(false);
//归还连接时执行validationQuery检测连接是否有效,配置为true会降低性能
dataSource.setTestOnReturn(false);
return dataSource;
}
@Bean(name = "secondarySqlSessionFactory")
public SqlSessionFactory test1SqlSessionFactory(@Qualifier("secondaryDataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
bean.setMapperLocations(
// 设置mybatis的xml所在位置
new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/secondary/*.xml"));
return bean.getObject();
}
@Bean("secondarySqlSessionTemplate")
public SqlSessionTemplate primarySqlsessiontemplate(
@Qualifier("secondarySqlSessionFactory") SqlSessionFactory sessionfactory) {
return new SqlSessionTemplate(sessionfactory);
}
}
至此,多数据源配置成功。