暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

springboot配置多个数据源

原创 钱多多 2022-07-21
1074

前言,什么是数据源与数据库连接池:

        说SpringBoot的多数据源配置之前,我们先了解下DataSource。

        在java中,操作数据库有很多方式,在众多方式中除了JDBC外还有DataSource对象。

DataSource可以看作数据源

        它封装了数据库参数,连接数据库,程序中操作DataSource对象即可对数据库进行增删改查操作。

        不同方式中使用的DataSource对象不同。列举如下:

        dbcp框架中的DataSource类是:org.apache.commons.dbcp.BasicDataSource

        c3p0框架的DataSource类是:com.mchange.v2.c3p0.ComboPooledDataSource

        MyBatis框架的DataSource类是:org.apache.ibatis.datasource.pooled.PooledDataSource

        Druid框架的DataSource类是:com.alibaba.druid.pool.DruidDataSource

        对于DataSource的一些实现,经常被叫做数据库连接池

        比如Druid官方文档中说“Druid是Java语言中最好的数据库连接池“,本质核心就是DataSource的一个实现类,作为中间层使用,并且基本上都提供了附带的其他的服务,也就是说不仅仅实现了核心建筑,也基于核心之上构建了很多的外围建设。

·

数据源和数据库连接池的关系:

  •         数据源建立多个数据库连接,这些数据库连接会保存在数据库连接池中,
  •         当需要访问数据库时,只需要从数据库连接池中获取空闲的数据库连接,
  •         当程序访问数据库结束时,数据库连接会放回数据库连接池中。


        在最开始学习JDBC的时候,我们自己获取一个数据连接的操作是这样的:

      学习JDBC的时候,直接使用DriverManager的这种形式,通常需要将驱动程序硬编码到项目中(JDBC4.0后可以自动注册驱动程序)。

        而且最重要的是通过DriverManager的getConnection方法获取的连接,是建立与数据库的连接。

        但是建立与数据库的连接是一项较耗资源的工作,频繁的进行数据库连接建立操作会产生较大的系统开销。

        DataSource中获取的连接来自于连接池中,虽然池中的连接从根本上来说其实也还是从DriverManager获取而来。

        DataSource就是DriverManager的一种替代角色,拥有对外提供连接的能力。


接下来看SpringBoot如何整合多数据源。


一,配置文件进行配置:

1,导入依赖:

        如果你新增的数据库数据源和目前的数据库不同,记得引入新数据库的驱动依赖,比如 MySQL 和 PGSQL。


  1. <dependency>


  2. <groupId>mysql</groupId>


  3. <artifactId>mysql-connector-java</artifactId>


  4. <scope>runtime</scope>


  5. </dependency>



  6. <dependency>


  7. <groupId>org.postgresql</groupId>


  8. <artifactId>postgresql</artifactId>


  9. <version>42.2.7</version>


  10. </dependency>

        首先,需要在配置文件中配置多数据源的连接信息;

  • 这里采用yml配置文件,其他类型配置文件同理
  • 我配置了两个数据源,一个名字叫ds1数据源,一个名字叫ds2数据源,如果你想配置更多的数据源,继续加就行了。

  1. spring:


  2. # 数据源配置


  3. datasource:


  4. ds1: #数据源1


  5. driver-class-name: com.mysql.jdbc.Driver # mysql的驱动你可以配置别的关系型数据库


  6. url: jdbc:mysql://ip:3306/db1 #数据源地址


  7. username: root # 用户名


  8. password: root # 密码


  9. ds2: # 数据源2


  10. driver-class-name: com.mysql.jdbc.Driver # mysql的驱动你可以配置别的关系型数据库


  11. url: jdbc:mysql://ip:3307/db2#数据源地址


  12. username: root # 用户名


  13. password: root # 密码



二,编写配置类:

编写Springboot的配置类:

        mybatis多数据源切换的原理是根据不同包,调用不同的数据源,

        你只需要把你的mapper.java和mapper.xml 写在某个package中,springboot自动帮你实现数据源切换。

核心代码就这两句:

1,用来指定包扫描、指定sqlSessionTemplateRef;


  1. @MapperScan(basePackages ="com.web.ds2.**.dao",


  2. sqlSessionTemplateRef = "ds2SqlSessionTemplate")

 2,用来指定mapper.xml的路径;


  1. sqlSessionFactory.


  2. setMapperLocations(new PathMatchingResourcePatternResolver().


  3. getResources("classpath*:com/web/ds2/**/*.xml"));


详细代码如下:

Mybatis主数据源ds1配置:


  1. /**


  2. * Mybatis主数据源ds1配置


  3. * 多数据源配置依赖数据源配置


  4. * @see DataSourceConfig


  5. */


  6. @Configuration


  7. @MapperScan(basePackages ="com.web.ds1.**.dao", sqlSessionTemplateRef = "ds1SqlSessionTemplate")


  8. public class MybatisPlusConfig4ds1 {



  9. @Bean(name = "dataSource1")


  10. @ConfigurationProperties(prefix = "spring.datasource.ds1")


  11. @Primary


  12. public DataSource dataSource() {


  13. return DataSourceBuilder.create().build();


  14. }



  15. //主数据源 ds1数据源


  16. @Primary


  17. @Bean("ds1SqlSessionFactory")


  18. public SqlSessionFactory ds1SqlSessionFactory(@Qualifier("ds1DataSource") DataSource dataSource) throws Exception {


  19. MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();


  20. sqlSessionFactory.setDataSource(dataSource);


  21. sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().


  22. getResources("classpath*:com/web/ds1/**/*.xml"));


  23. return sqlSessionFactory.getObject();


  24. }



  25. @Primary


  26. @Bean(name = "ds1TransactionManager")


  27. public DataSourceTransactionManager ds1TransactionManager(@Qualifier("ds1DataSource") DataSource dataSource) {


  28. return new DataSourceTransactionManager(dataSource);


  29. }



  30. @Primary


  31. @Bean(name = "ds1SqlSessionTemplate")


  32. public SqlSessionTemplate ds1SqlSessionTemplate(@Qualifier("ds1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {


  33. return new SqlSessionTemplate(sqlSessionFactory);


  34. }



  35. }

 Mybatis第二个ds2数据源配置:


  1. /**


  2. * Mybatis 第二个ds2数据源配置


  3. * 多数据源配置依赖数据源配置


  4. * @see DataSourceConfig


  5. */


  6. @Configuration


  7. @MapperScan(basePackages ="com.web.ds2.**.dao", sqlSessionTemplateRef = "ds2SqlSessionTemplate")


  8. public class MybatisPlusConfig4ds2 {



  9. @Bean(name = "dataSource2")


  10. @ConfigurationProperties(prefix = "spring.datasource.ds2")


  11. public DataSource dataSource() {


  12. return DataSourceBuilder.create().build();


  13. }



  14. //ds2数据源


  15. @Bean("ds2SqlSessionFactory")


  16. public SqlSessionFactory ds2SqlSessionFactory(@Qualifier("ds2DataSource") DataSource dataSource) throws Exception {


  17. MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();


  18. sqlSessionFactory.setDataSource(dataSource);


  19. sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().


  20. getResources("classpath*:com/web/ds2/**/*.xml"));


  21. return sqlSessionFactory.getObject();


  22. }



  23. //事务支持


  24. @Bean(name = "ds2TransactionManager")


  25. public DataSourceTransactionManager ds2TransactionManager(@Qualifier("ds2DataSource") DataSource dataSource) {


  26. return new DataSourceTransactionManager(dataSource);


  27. }



  28. @Bean(name = "ds2SqlSessionTemplate")


  29. public SqlSessionTemplate ds2SqlSessionTemplate(@Qualifier("ds2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {


  30. return new SqlSessionTemplate(sqlSessionFactory);


  31. }



  32. }


代码解释:

  • @ConfigurationProperties(prefix = "spring.datasource.ds1"):使用spring.datasource.ds1开头的配置。

        @Qualifier:指定数据源名称,与Bean中的name属性原理相同,主要是为了确保注入成功;

        @Primary:声明这是一个主数据源(默认数据源),多数据源配置时必不可少。

  • @Primary :声明这是一个主数据源(默认数据源),多数据源配置时必不可少
  • @Qualifier:显式选择传入的 Bean。

`

注意:

        因为已经在两个数据源中分别配置了扫描的 Mapper 路径,如果你之前在 SpringBoot 启动类中也使用了 Mapper 扫描注解,需要删掉

·

·

四,测试与使用:

Service层:


  1. @Service


  2. public class TestService {



  3. @Resource


  4. private ClusterMapper clusterMapper;


  5. @Resource


  6. private MasterMapper masterMapper;



  7. public List<HashMap<String, Object>> queryBooks() {


  8. return masterMapper.queryBooks(); //指定的配置类扫描的是一个包


  9. }



  10. public List<HashMap<String, Object>> queryOrders() {


  11. return clusterMapper.queryOrders(); //指定的配置类扫描的是另一个包


  12. }


  13. }

Controller层:


  1. @RestController


  2. @RequestMapping(value = "/test", method = RequestMethod.POST)


  3. public class TestController {


  4. @Resource


  5. private TestService testService;



  6. @RequestMapping("/books")


  7. public List<HashMap<String, Object>> queryBooks() {


  8. return testService.queryBooks();


  9. }



  10. @RequestMapping("/orders")


  11. public List<HashMap<String, Object>> queryOrders() {


  12. return testService.queryOrders();


  13. }


  14. }


五,拓展

连接池:

        其实在多数据源改造中,我们一般情况下都不会使用默认的 JDBC 连接方式,往往都需要引入连接池进行连接优化,不然你可能会经常遇到数据源连接被断开等报错日志。

        其实数据源切换连接池数据源也是十分简单的,直接引入连接池依赖,然后把创建 dataSource 的部分换成连接池数据源创建即可


下面以阿里的 Druid 为例,先引入连接池数据源依赖。


  1. <dependency>


  2. <groupId>com.alibaba</groupId>


  3. <artifactId>druid</artifactId>


  4. </dependency>

配置文件中,添加 Druid 的一些配置。


  1. spring.datasource.datasource2.initialSize=3 # 根据自己情况设置


  2. spring.datasource.datasource2.minIdle=3


  3. spring.datasource.datasource2.maxActive=20

改写 dataSource 这个Bean 的创建代码部分:


  1. /**


  2. * Mybatis 第二个ds2数据源配置


  3. * 多数据源配置依赖数据源配置


  4. * @see DataSourceConfig


  5. */


  6. @Configuration


  7. @MapperScan(basePackages ="com.web.ds2.**.dao", sqlSessionTemplateRef = "ds2SqlSessionTemplate")


  8. public class MybatisPlusConfig4ds2 {



  9. @Value("${spring.datasource.datasource2.jdbc-url}")


  10. private String url;


  11. @Value("${spring.datasource.datasource2.driver-class-name}")


  12. private String driverClassName;


  13. @Value("${spring.datasource.datasource2.username}")


  14. private String username;


  15. @Value("${spring.datasource.datasource2.password}")


  16. private String password;


  17. @Value("${spring.datasource.datasource2.initialSize}")


  18. private int initialSize;


  19. @Value("${spring.datasource.datasource2.minIdle}")


  20. private int minIdle;


  21. @Value("${spring.datasource.datasource2.maxActive}")


  22. private int maxActive;



  23. @Bean(name = "dataSource2")


  24. public DataSource dataSource() {


  25. DruidDataSource dataSource = new DruidDataSource();


  26. dataSource.setUrl(url);


  27. dataSource.setDriverClassName(driverClassName);


  28. dataSource.setUsername(username);


  29. dataSource.setPassword(password);


  30. dataSource.setInitialSize(initialSize);


  31. dataSource.setMinIdle(minIdle);


  32. dataSource.setMaxActive(maxActive);


  33. return dataSource;


  34. }



  35. //...



  36. }



建议:

        建议去使用mybatis-plus 集成 多数据源。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论