码迷,mamicode.com
首页 > 编程语言 > 详细

[SpringBoot]快速配置多数据源(整合MyBatis)

时间:2020-12-11 12:15:32      阅读:8      评论:0      收藏:0      [点我收藏+]

标签:sea   home   实战   添加   完成   ring   pack   生成密钥   创建   

技术图片

前言

由于业务需求,需要同时在SpringBoot中配置两套数据源(连接两个数据库),要求能做到service层在调用各数据库表的mapper时能够自动切换数据源,也就是mapper自动访问正确的数据库。

本文内容:

  • 在Springboot+Mybatis项目的基础上,学习多数据源的快速配置
  • 避免网上某些配置数据源文章的深坑

SpringBoot实战系列教程回顾:

  • SpringCache + Redis实现数据缓存

  • [Springboot]发送邮件、重置密码业务实战

  • [Springboot]整合ElasticSearch实现数据模糊搜索(Logstash同步Mysql数据)

正文

多数据源配置实战(整合MyBatis)

SpringBoot版本:2.0.6.RELEASE

项目结构图(原谅我保护隐私代码):
技术图片
image.png

排除SpringBoot的自动配置类DataSourceAutoConfiguration

首先要在@SpringBootApplication排除该类,因为它会读取application.properties文件的spring.datasource.*属性并自动配置单数据源

@SpringBootApplication(exclude = {
        DataSourceAutoConfiguration.class
})

在application.properties中配置多数据源连接信息

你需要连接多少个数据库源,就配置几个,名字可以自由命名代替db1,db2

# database
db.conn.str = useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useLocalSessionState=true&tinyInt1isBit=false

spring.datasource.db1.jdbc-url=jdbc:mysql://xxxx1:xxxx/xxxxx1?${db.conn.str}
spring.datasource.db1.username=xxxxx
spring.datasource.db1.password=xxxxx
spring.datasource.db1.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.db2.jdbc-url=jdbc:mysql://xxxxx2:xxxx/xxxxx2?${db.conn.str}
spring.datasource.db2.username=xxxxx
spring.datasource.db2.password=xxxxx
spring.datasource.db2.driver-class-name=com.mysql.jdbc.Driver

注意:这里请一定将spring.datasource.db1.url改为spring.datasource.db1.jdbc-url

官方文档的解释是:因为连接池的实际类型没有被公开,所以在您的自定义数据源的元数据中没有生成密钥,而且在IDE中没有完成(因为DataSource接口没有暴露属性)。另外,如果您碰巧在类路径上有Hikari,那么这个基本设置就不起作用了,因为Hikari没有url属性(但是确实有一个jdbcUrl属性)。在这种情况下,您必须重写您的配置如下:

手动创建数据库配置类

由于我们禁掉了自动数据源配置,因为下一步就需要手动将这些数据源创建出来,创建DataSourceConfig类

@Configuration
public class DataSourceConfig {

    @Bean(name = "db1")
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    public DataSource businessDbDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "db2")
    @ConfigurationProperties(prefix = "spring.datasource.db2")
    public DataSource newhomeDbDataSource() {
        return DataSourceBuilder.create().build();
    }
}

分别配置不同数据源的mybatis的SqlSessionFactory

这样做可以让我们的不同包名底下的mapper自动使用不同的数据源

创建Db1Config:

/**
 * @author yangzhendong01
 */
@Configuration
@MapperScan(basePackages = {"com.xxxxx.webApi.mapper.db1"}, sqlSessionFactoryRef = "sqlSessionFactoryDb1")
public class Db1Config {

    @Autowired
    @Qualifier("db1")
    private DataSource dataSourceDb1;

    @Bean
    public SqlSessionFactory sqlSessionFactoryDb1() throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSourceDb1);
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/db1/*.xml"));
        return factoryBean.getObject();
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplateDb1() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactoryDb1());
    }

}

创建Db2Config:

/**
 * @author yangzhendong01
 */
@Configuration
@MapperScan(basePackages = {"com.xxxxx.webApi.mapper.db2"}, sqlSessionFactoryRef = "sqlSessionFactoryDb2")
public class Db2Config {

    @Autowired
    @Qualifier("db2")
    private DataSource dataSourceDb2;

    @Bean
    public SqlSessionFactory sqlSessionFactoryDb2() throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSourceDb2);
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/db2/*.xml"));
        return factoryBean.getObject();
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplateDb2() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactoryDb2());
    }

}

注意:此步一定要添加mapper.xml文件扫描路径,否则报错Invalid bound statement (not found)

factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/xxxxxx/*.xml"));

完成这些配置后,假设我们有2个Mapper :

mapper.db1.xxxMapper和mapper.db2.xxxMapper

我们在程序的任何位置使用前者时会自动连接db1库,后者连接db2库。

参考文献

主要参考:

https://blog.csdn.net/neosmith/article/details/61202084

其他参考:

http://blog.didispace.com/springbootmultidatasource/

总结

本文在一个Springboot+Mybatis项目的基础上,学习多数据源的快速配置。

祝大家国庆节假期快乐!

关注我

我目前是一名后端开发工程师。主要关注后端开发,数据安全,边缘计算等方向。

微信:yangzd1102(请注明来意)

Github:@qqxx6661

个人博客:

  • CSDN:@Rude3Knife
  • 知乎:@Zhendong
  • 简书:@蛮三刀把刀
  • 掘金:@蛮三刀把刀

原创博客主要内容

  • Java知识点复习全手册
  • Leetcode算法题解析
  • 剑指offer算法题解析
  • SpringCloud菜鸟入门实战系列
  • SpringBoot菜鸟入门实战系列
  • 爬虫相关技术文章
  • 后端开发相关技术文章

个人公众号:后端技术漫谈

技术图片
公众号201992.jpg

如果文章对你有帮助,不妨收藏起来并转发给您的 朋友们~

[SpringBoot]快速配置多数据源(整合MyBatis)

标签:sea   home   实战   添加   完成   ring   pack   生成密钥   创建   

原文地址:https://blog.51cto.com/15047490/2560744

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!