目录
前言
此文介绍的是在SpringBoot中使用Mybatis配置多数据源(多个数据库),整合Druid
网上有很多文章,翻了翻,但是都有问题啊,有的是没使用Druid,使用了默认的Hirika,有的是配置文件不给或者给的是Hirika能用的配置,层级不对,所以我自己来记一下
代码
pom文件maven依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
yml配置文件结构
数据源配置放druid下面
不使用Druid,url就不用改成jdbc-url
使用mybatis这种方式配置,不指定线程池的话,默认的连接池是Hirika
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
datasource1:
name: datasource1
url: *********
username: *********
password: *********
driver-class-name: *********
datasource2:
name: datasource2
url: *********
username: *********
password: *********
driver-class-name: *********
多数据源配置类
此类指定有多少个数据源,我配了datasource1、datasource2两个
关键点在于return的类型,网上很多配置多数据源的文章使用return DataSourceBuilder.create().build(); ,这样的话连接池是Hirika,参考DataSourceBuilder源码如下
1.@Bean(name = “datasource1”)
指定数据源bean的name
2.@ConfigurationProperties(prefix = “spring.datasource.druid.datasource1”)
指定读取yml中配置的路径
3.return new DruidDataSource();
指定连接池为Druid
import javax.sql.DataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.alibaba.druid.pool.DruidDataSource;
@Configuration
public class DataSourceConfig {
@Bean(name = "datasource1")
@ConfigurationProperties(prefix = "spring.datasource.druid.datasource1")
public DataSource dataSource1() {
return new DruidDataSource();
}
@Bean(name = "datasource2")
@ConfigurationProperties(prefix = "spring.datasource.druid.datasource2")
public DataSource dataSource2() {
return new DruidDataSource();
}
}
主数据源具体配置
这个类用来配置主数据源
1.@MapperScan(basePackages = {“com.oxye.mapper.ds1”}, sqlSessionFactoryRef = “sqlSessionFactoryDs1”)
basePackages 指定扫描mapper的路径
sqlSessionFactoryRef 关联bean sqlSessionFactoryDs1
2.@Autowired
@Qualifier(“datasource1”)
private DataSource datasource1;
指定数据源
3.@Primary
指定本数据源的SqlSessionFactory、SqlSessionTemplate、DataSourceTransactionManager为主要bean,项目启动、运行时寻找相关bean时,会使用带@Primary注解的bean,如果都不配置@Primary,系统会报错,不知选择哪个bean
4.factoryBean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources(“classpath:/mapperDs1/*.xml”)
);
设置mapper.xml文件的路径,yml中的mybatis可以去掉
mybatis:mapper-locations:*** 了
import javax.sql.DataSource;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@Configuration
@MapperScan(basePackages = {
"com.oxye.mapper.ds1"}, sqlSessionFactoryRef = "sqlSessionFactoryDs1")
public class MybatisMasterConfig {
@Autowired
@Qualifier("datasource1")
private DataSource datasource1;
@Bean
@Primary
public SqlSessionFactory sqlSessionFactoryDs1() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(datasource1);
factoryBean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath:/mapperDs1/*.xml")
);
return factoryBean.getObject();
}
@Bean
@Primary
public SqlSessionTemplate sqlSessionFactoryDs1() throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactoryDs1());
return template;
}
@Bean(name = "masterTransactionManager")
@Primary
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(datasource1);
}
}
其他数据源具体配置类
和主数据源配置差不多,区别是不用设置@Primary,如果你希望主sqlSession是主数据源,事务优先使用此数据源,可以把@Primary移动到这里
import javax.sql.DataSource;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@Configuration
@MapperScan(basePackages = {
"com.oxye.mapper.ds2"}, sqlSessionFactoryRef = "sqlSessionFactoryDs2")
public class MybatisSlaveConfig {
@Autowired
@Qualifier("datasource2")
private DataSource datasource2;
@Bean
public SqlSessionFactory sqlSessionFactoryDs2() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(datasource2);
factoryBean.setMapperLocations(
//设置mybatis的xml所在位置
new PathMatchingResourcePatternResolver().getResources("classpath:/mapperDs2/*.xml")
);
return factoryBean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplateDs2() throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactoryDs2());
return template;
}
@Bean(name = "transactionManager")
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(datasource2);
}
}
相关问题
1.报错无jdbc-url
说明Druid没生效,使用的是默认的Hirika,所以需要jdbc-url,Druid是可以用url的
2.查看源码时发现connect是Hirika的
因为数据源应该返回return new DruidDataSource(); ,而不是
return DataSourceBuilder.create().build();
3.绑定异常 BindingException
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
看看你mapper的路径是不是配错了
4.启动创建bean冲突 UnsatisfiedDependencyException
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘***’
@Bean注解的类或方法默认使用小写开头的类名、文件名,看看是不是重复了,重复的话使用@Bean的name指定名称,注入其他bean时使用@Qualifier("***")指定bean名称
5.启动或运行时,报错找到多个bean required a single bean, but 2 were found:
***required a single bean, but 2 were found
使用@Primary指定主数据源、主事务管理器
参考:
这篇配置后使用的不是Druid
这篇过于实用,没解决问题
这篇较为全,但是其实没用到Druid,评论区很精彩