在实际开发过程中,项目往往会同时用到多个数据源,访问不同的数据库的情况,在SpringBoot项目中可以参考以下配置。
1.application.yml中的配置
spring:
datasource:
szy:
type: com.zaxxer.hikari.HikariDataSource
username: ****
password: *****
jdbc-url: jdbc:dm://localhost:5240/TEST?useUnicode=true&characterEncoding=gbk&useSSL=true&serverTimezone=UTC
driver-class-name: dm.jdbc.driver.DmDriver
hikari:
maximum-pool-size: 20
sms:
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc-url: jdbc:sqlserver://localhost:1430;DatabaseName=TEST
username: ***
password: *****
在application.yml中给每个数据源都配置一个别名,如上面代码中的 szy 和 sms 加以区分。不同数据库的驱动jar包就自己去下载了。
2.在项目中添加两个config的配置类,作为数据源配置。如图所示:
参考代码如下:
package com.cq.duty.config;
import org.apache.ibatis.session.LocalCacheScope;
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.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.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
/**
* @Author: admin
* @Despriction:
* @Package: com.cq.duty.config
* @Date:Created in 2021/1/21 16:53
* @Modify By:
*/
@Configuration
//表示dao层文件应从哪里进行读取
@MapperScan(basePackages = {"com.cq.duty.mapper","com.cq.base.mapper"}, sqlSessionFactoryRef = "szySqlSessionFactory")
public class SzyDruidConfig {
@Primary // 表示这个数据源是默认数据源, 这个注解必须要加,因为不加的话spring将分不清楚那个为主数据源(默认数据源)
@Bean("szyDataSource")
@ConfigurationProperties(prefix = "spring.datasource.szy") //读取application.yml中的配置参数映射成为一个对象
public DataSource getDbDataSource(){
return DataSourceBuilder.create().build();
}
@Primary
@Bean("szySqlSessionFactory")
public SqlSessionFactory dbSqlSessionFactory(@Qualifier("szyDataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
configuration.setCacheEnabled(false);//取消mybatis缓存
configuration.setLocalCacheScope(LocalCacheScope.STATEMENT);
bean.setConfiguration(configuration);//将修改后的configuration从新赋值
// mapper的xml形式文件位置必须要配置,不然将报错:no statement (这种错误也可能是mapper的xml中,namespace与项目的路径不一致导致)
bean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:mapper/**.xml"));//表示dao层对应的xml文件的扫描读取路径
return bean.getObject();
}
@Primary
@Bean("szySqlSessionTemplate")
public SqlSessionTemplate dbSqlSessionTemplate(@Qualifier("szySqlSessionFactory")
SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
}
package com.cq.duty.config;
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.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.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
/**
* @Author: admin
* @Despriction:
* @Package: com.cq.duty.config
* @Date:Created in 2021/1/21 17:06
* @Modify By:
*/
@Configuration
//表示dao层文件应从哪里进行读取
@MapperScan(basePackages = "com.cq.duty.smsdao", sqlSessionFactoryRef = "smsSqlSessionFactory")
public class SmsDruidConfig {
@Bean("smsDataSource")
@ConfigurationProperties(prefix = "spring.datasource.sms")
public DataSource getDbDataSource(){
return DataSourceBuilder.create().build();
}
@Bean("smsSqlSessionFactory")
public SqlSessionFactory dbSqlSessionFactory(@Qualifier("smsDataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:mapper/smsMapper/*.xml"));
return bean.getObject();
}
@Bean("smsSqlSessionTemplate")
public SqlSessionTemplate dbSqlSessionTemplate(@Qualifier("smsSqlSessionFactory")
SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
}
如代码中的注释锁描述的那样,有三个地方应也别注意
一是@MapperScan中配置的dao层扫描路径,多个数据源则应该配置多个dao层,不能放在同一个目录下。
二是在SqlSessionFactory 中的 bean.setMapperLocations 中配置dao层所对应的xml文件的扫描路径,多个数据源对应的此处路径也是不一致的。
三是通过以上配置之后在yml中关于mybatis的配置和在启动类上的@MapperScan的配置可能会失效不再起作用。
如此之后则完成了多数据源的配置。
项目多数据源完整配置路径参考如下图: