正确可用版:SpringBoot+Mybatis-plus+Druid 实现配置多数据源(数据库)
前言此文介绍的是在SpringBoot中使用Mybatis配置多数据源(多个数据库),整合Druid网上有很多文章,翻了翻,但是都有问题啊,有的是没使用Druid,使用了默认的Hirika,有的是配置文件不给或者给的是Hirika能用的配置,层级不对,所以我自己来记一下代码pom文件maven依赖<dependency><groupId>com.alibaba</gr
目录
前言
此文介绍的是在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: *********
properties版
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.initialSize=5
spring.datasource.druid.minIdle=5
spring.datasource.druid.maxActive=20
spring.datasource.druid.maxWait=60000
spring.datasource.druid.datasource1.name=datasource1
spring.datasource.druid.datasource1.url=jdbc:mysql://ip:port/数据库名
spring.datasource.druid.datasource1.username=11
spring.datasource.druid.datasource1.password=11
spring.datasource.druid.datasource1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.datasource2.name=datasource2
spring.datasource.druid.datasource2.url=jdbc:mysql://ip:port/数据库名
spring.datasource.druid.datasource2.username=11
spring.datasource.druid.datasource2.password=11
spring.datasource.druid.datasource2.driver-class-name=com.mysql.cj.jdbc.Driver
多数据源配置类
注意,Mybatis-plus使用MybatisSqlSessionFactoryBean ,纯Mybatis使用SqlSessionFactoryBean
此类指定有多少个数据源,我配了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 com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
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.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = {"com.ais.cdc.mapper"}, sqlSessionFactoryRef = "sqlSessionFactoryDs1")
public class MybatisMasterConfig {
@Autowired
@Qualifier("datasource1")
private DataSource datasource1;
@Bean
@Primary
public SqlSessionFactory sqlSessionFactoryDs1() throws Exception {
MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
factoryBean.setDataSource(datasource1);
factoryBean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*.xml")
);
//向Mybatis过滤器链中添加拦截器
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
factoryBean.setPlugins(interceptor);
return factoryBean.getObject();
}
@Bean
@Primary
public SqlSessionTemplate sqlSessionTemplateDs1() throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactoryDs1());
return template;
}
@Bean
@Primary
public DataSourceTransactionManager transactionManager1() {
return new DataSourceTransactionManager(datasource1);
}
}
其他数据源具体配置类
和主数据源配置差不多,区别是不用设置@Primary,如果你希望主sqlSession是主数据源,事务优先使用此数据源,可以把@Primary移动到这里
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
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.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = {"com.ais.cdc.mapper2"}, sqlSessionFactoryRef = "sqlSessionFactoryDs2")
public class MybatisSlaveConfig {
@Autowired
@Qualifier("datasource2")
private DataSource datasource2;
@Bean
public SqlSessionFactory sqlSessionFactoryDs2() throws Exception {
MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
factoryBean.setDataSource(datasource2);
factoryBean.setMapperLocations(
//设置mybatis的xml所在位置
new PathMatchingResourcePatternResolver().getResources("classpath:/mapper2/*.xml")
);
return factoryBean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplateDs2() throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactoryDs2());
return template;
}
@Bean
public DataSourceTransactionManager transactionManager2() {
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指定主数据源、主事务管理器
6.Mybatis-Plus-Join拦截器未注入
找到com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration,重写这个类,手动注入拦截器,如下:
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.getDbType(databaseIdProvider.getDatabaseId(datasource1))));
factory.setPlugins(interceptor, new SpecialCharInterceptor(), this.interceptors[0]);
参考:
这篇配置后使用的不是Druid
这篇过于实用,没解决问题
这篇较为全,但是其实没用到Druid,评论区很精彩
更多推荐
所有评论(0)