在实际项目中,尤其是复杂系统,往往需要连接多个数据源,实现多数据库读写,这时就需要配置多数据源连接,而Spring Boot整合MybatisPlus实现多数据源有两种方式:分包 和 AOP。习惯问题,这里讲的是分包方式实现,借用网上的一张图说明很清晰了:
文章图片
本文在已经配置好mybatisPlus和druid的前提下增加为多数据源的,不清楚可以参考前面的文章
数据源配置 properties.xml中设置两个数据源,假设这里的数据库分别为mickey和tianji
spring.datasource.druid.mickey.jdbc-url=你的数据库地址
spring.datasource.druid.mickey.username=mickey
spring.datasource.druid.mickey.password=***
spring.datasource.druid.mickey.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.mickey.type=com.alibaba.druid.pool.DruidDataSourcespring.datasource.druid.tianji.jdbc-url=你的数据库地址
spring.datasource.druid.tianji.username=tianji
spring.datasource.druid.tianji.password=***
spring.datasource.druid.tianji.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.tianji.type=com.alibaba.druid.pool.DruidDataSource
创建配置文件 数据源1配置 数据源1为默认数据源,需要使用注解 @Primary
@Configuration
@MapperScan(basePackages = "com.demo.mapper.mickey", sqlSessionTemplateRef = "mickeySqlSessionTemplate")
public class MickeyDsConfig {@Primary
@Bean(name = "mickey")
@ConfigurationProperties(prefix = "spring.datasource.druid.mickey")
public DataSource mickeyDataSource() {
return DataSourceBuilder.create().build();
}@Primary
@Bean(name = "mickeySqlSessionFactory")
public SqlSessionFactory mickeySqlSessionFactory(@Qualifier("mickey") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}@Primary
@Bean(name = "mickeyTransactionManager")
public DataSourceTransactionManager mickeyTransactionManager(@Qualifier("mickey") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}@Primary
@Bean(name = "mickeySqlSessionTemplate")
public SqlSessionTemplate mickeySqlSessionTemplate(@Qualifier("mickeySqlSessionFactory") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}}
数据源2配置
@Configuration
@MapperScan(basePackages = "com.demo.mapper.tianji", sqlSessionTemplateRef = "tianjiSqlSessionTemplate")
public class TianjiDsConfig {@Bean(name = "tianji")
@ConfigurationProperties(prefix = "spring.datasource.druid.tianji")
public DataSource tianjiDataSource() {
return DataSourceBuilder.create().build();
}@Bean(name = "tianjiSqlSessionFactory")
public SqlSessionFactory tianjiSqlSessionFactory(@Qualifier("tianji") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}@Bean(name = "tianjiTransactionManager")
public DataSourceTransactionManager tianjiTransactionManager(@Qualifier("tianji") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}@Bean(name = "tianjiSqlSessionTemplate")
public SqlSessionTemplate tianjiSqlSessionTemplate(@Qualifier("tianjiSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}}
到这里,查询数据正常了,但是遇到了一个问题,发现分页查询无效了,不只是分页查询,此前配置的乐观锁插件,防止全表更新与删除全部都失效了,解决方法:需要在配置数据源时,重新将插件注入到数据源中。
修改mybatisPlus配置 将插件plugins汇总起来
@EnableTransactionManagement
@Configuration
public class MybatisPlusConfig {@Bean(name = "plugins")
public Interceptor[] plugins() {
return new Interceptor[]{ optimisticLockerInnerInterceptor(),paginationInterceptor(), blockAttackInnerInterceptor() };
}/** 乐观锁插件 */
@Bean(name = "optimisticLockerInnerInterceptor")
public MybatisPlusInterceptor optimisticLockerInnerInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}/** 分页插件 */
@Bean(name = "paginationInterceptor")
public MybatisPlusInterceptor paginationInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
/* 单页分页条数限制 */
pageInterceptor.setMaxLimit(20L);
interceptor.addInnerInterceptor(pageInterceptor);
return interceptor;
}/** 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除) */
@Bean(name = "configurationCustomizer")
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> configuration.setUseDeprecatedExecutor(false);
}/** 防止全表更新与删除 */
@Bean(name = "blockAttackInnerInterceptor")
public MybatisPlusInterceptor blockAttackInnerInterceptor() {
/**去除警告,目前暂时无影响,持续关注*/
disableWarning();
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
/*针对 update 和 delete 语句*/
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
return interceptor;
}/**
* 去除Warning
*/
private static void disableWarning() {
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe u = (Unsafe) theUnsafe.get(null);
Class cls = Class.forName("jdk.internal.module.IllegalAccessLogger");
Field logger = cls.getDeclaredField("logger");
u.putObjectVolatile(cls, u.staticFieldOffset(logger), null);
} catch (Exception e) {
}
}}
将SqlSessionFactoryBean改用MybatisSqlSessionFactoryBean,将plugins重新注入数据源配置中
@Autowired
@Qualifier("plugins")
private Interceptor[] plugins;
@Primary
@Bean(name = "mickeySqlSessionFactory")
public SqlSessionFactory mickeySqlSessionFactory(@Qualifier("mickey") DataSource dataSource) throws Exception {
//SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
/** 当使用myBatis-plus的时候需要使用 MybatisSqlSessionFactoryBean */
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
bean.setDataSource(dataSource);
/**当使用多数据源时,mybatisPlus默认配置将会失效,需要单独将其注入数据源中 */
bean.setPlugins(plugins);
return bean.getObject();
}
完整的文件为
@Configuration
@MapperScan(basePackages = "com.demo.mapper.mickey", sqlSessionTemplateRef = "mickeySqlSessionTemplate")
public class MickeyDsConfig {@Autowired
@Qualifier("plugins")
private Interceptor[] plugins;
@Primary
@Bean(name = "mickey")
@ConfigurationProperties(prefix = "spring.datasource.druid.mickey")
public DataSource mickeyDataSource() {
return DataSourceBuilder.create().build();
}@Primary
@Bean(name = "mickeySqlSessionFactory")
public SqlSessionFactory mickeySqlSessionFactory(@Qualifier("mickey") DataSource dataSource) throws Exception {
//SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
/** 当使用myBatis-plus的时候需要使用 MybatisSqlSessionFactoryBean */
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
bean.setDataSource(dataSource);
/**当使用多数据源时,mybatisPlus默认配置将会失效,需要单独将其注入数据源中 */
bean.setPlugins(plugins);
return bean.getObject();
}@Primary
@Bean(name = "mickeyTransactionManager")
public DataSourceTransactionManager mickeyTransactionManager(@Qualifier("mickey") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}@Primary
@Bean(name = "mickeySqlSessionTemplate")
public SqlSessionTemplate mickeySqlSessionTemplate(@Qualifier("mickeySqlSessionFactory") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}}
【java后端|spring boot使用druid多数据源配置】总结:
- 分包配置的方法,使用多数据源查询,结构更加清晰
推荐阅读
- 接口自动化测试框架|接口自动化--数据库
- 测试|jmeter系列(关联数据库)
- Java基础与算法|Linux学习(二)---实操篇1远程登录
- SQL|MySQL之增删改查,常用函数
- MyBatisPlus|MyBatis-Plus工具
- MySQL|MySQL表的增删改查(进阶)
- SQL|python操作mysql插入数据
- ClickHouse
- MacOS新功能“通用控制”,多台设备操作互联太方便了!