java后端|spring boot使用druid多数据源配置

在实际项目中,尤其是复杂系统,往往需要连接多个数据源,实现多数据库读写,这时就需要配置多数据源连接,而Spring Boot整合MybatisPlus实现多数据源有两种方式:分包 和 AOP。习惯问题,这里讲的是分包方式实现,借用网上的一张图说明很清晰了:
java后端|spring boot使用druid多数据源配置
文章图片

本文在已经配置好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多数据源配置】总结:
  • 分包配置的方法,使用多数据源查询,结构更加清晰

    推荐阅读