关于java:SpringBoot系列5项目中使用多个数据库

40次阅读

共计 4227 个字符,预计需要花费 11 分钟才能阅读完成。

内容概述

本文简要介绍下,当我的项目应用多个数据库的时候,druid 如何配置。

文章目录

在之前的文章,SpringBoot 系列:1. 疾速搭建 web api 我的项目,提到能够通过很简略的配置实现数据库的拜访,例如:

spring:
  datasource:
    druid:
      url: jdbc:mysql://localhost:3306/test_db?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
      username: root
      password: 123456

单个数据源的时候,只有加上这些配置,配置druid-spring-boot-starter。无需其余配置代码,就能够实现数据库的拜访。

然而理论利用中,即便是微服务,通常也须要拜访一个以上的数据库,这时候就须要做些额定的配置,来实现多数据源的拜访。上面咱们以两个数据源为例,展现下实现的过程。

1. 增加两个不同的配置到 application.xml 中

首先增加要拜访的两个数据源的配置信息,假如咱们有两个数据库,

  • test_db作为主库
  • biztest_db作为业务扩大库

则配置内容如下,这里放入 spring 的配置作比照,能够看到 dbconfig 是能够独立定义的配置,在程序中可通过 @ConfigurationProperties 注解获取。

spring:
  redis:
    database: 0
    host: localhost
    port: 6379
  session:
    store-type: redis
    timeout: 600s

dbconfig:
  maindb: ## 这里只是配置的名字,能够自定义,不会影响连贯
    url: jdbc:mysql://localhost:3306/test_db?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456
  bizdb: ## 这里只是配置的名字,能够自定义,不会影响连贯
    url: jdbc:mysql://localhost:6306/biztest_db?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: biz_rw
    password: 654321
2. 自定义配置类

为了实现对两个数据库的连贯,须要别离写两个配置类,配置类的次要性能是:

  • 依据不同的配置,生成不同的 mysql 连贯所需的 datasource 和 sqlsession 对象,用于对数据库的连贯拜访。
  • 通过 @MapperScan 注解,指定哪些 mapper 应用哪个 sqlsession 去拜访。

上面看配置类的源码,前面会具体的剖析下,首先是主库配置类:

@Configuration
@MapperScan(basePackages = "com.yourcom.proname.repository.mapper.testDb*", sqlSessionFactoryRef = "mainSqlSessionFactory")
public class MainDb {
    @Primary
    @Bean(name = "mainDataSource")
    @ConfigurationProperties(prefix = "dbconfig.maindb") // 获取 application.yml 外面的配置信息
    public DataSource druidDataSource() {return DruidDataSourceBuilder.create().build();}

    @Primary
    @Bean(name = "mainTransactionManager")
    public DataSourceTransactionManager masterTransactionManager(@Qualifier(value = "mainDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);
    }

    @Primary
    @Bean(name = "mainSqlSessionFactory")
    @ConfigurationPropertiesBinding()
    public SqlSessionFactory sqlSessionFactory(@Qualifier(value = "mainDataSource") DataSource dataSource) throws Exception {MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        return factoryBean.getObject();}
}

biz 扩大库的配置类:

@Configuration
@MapperScan(basePackages = "com.yourcom.proname.repository.mapper.bizDb*", sqlSessionFactoryRef = "bizSqlSessionFactory")
public class BizDb {@Bean(name = "bizDataSource")
    @ConfigurationProperties(prefix = "dbconfig.bizdb")
    public DataSource druidDataSource() {return DruidDataSourceBuilder.create().build();}

    @Bean(name = "bizTransactionManager")
    public DataSourceTransactionManager masterTransactionManager(@Qualifier(value = "bizDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "bizSqlSessionFactory")
    @ConfigurationPropertiesBinding()
    public SqlSessionFactory sqlSessionFactory(@Qualifier(value = "bizDataSource") DataSource dataSource) throws Exception {MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        return factoryBean.getObject();}
}

代码的具体解释:

  • 数据库拜访的流程中会创立两个比拟重要的对象,datasource 和 sqlsession。

    • 用于治理数据库的连贯和会话,不同的数据库要创立不同的配置。
    • 对应到下面代码中就是 mainDataSourcemainSqlSessionFactory,这里应用了 mybatis 中的 sqlsession。
  • @MapperScan,指定要扫描的 mapper 包,和这个包中的 mapper 要应用的 sqlsession。

    • 单数据源的时候不必写配置类,这个注解能够间接写在 WebDemoApplication 启动类下面。
    • 多数据源时,要别离写在每个数据源的配置类上,别离指定对应的 mapper 应用的 sqlsession。这样在开发时间接应用 mapper 就能够,会主动拜访对应的数据库。

配置之后通过生成工具,生成的代码构造如下,其中 testDb 中就是主库 test_db 的 mapper,bizDb 中就是扩大库 biztest_db 的 mapper。在 biztest_db 中,有一张表:user_account,对应的生成了 UserAccountMapper 实体类。

3. 在 controller 中应用

上面看下如何在 controller 中拜访不同数据库中的表。

这里实现一个接口,先通过 userId 判断主库中用户是否存在,而后获取用户的账户信息。

@RestController
public class UserController {
    @Resource
    IMainUserService mainUserService;

    @Resource
    IUserAccountService userAccountService;

    /**
     * 依据 id 获取用户账户信息
     *
     * @return
     */
    @GetMapping("user/account")
    public CommonResVo<UserAccount> getUserAccount(Integer userId) throws Exception {MainUser mainUser = mainUserService.getById(userId);
        if (mainUser == null) {throw new Exception("用户不存在");
        }
        UserAccount userAccount = userAccountService.getOne(new LambdaQueryWrapper<UserAccount>().eq(UserAccount::getUserId, mainUser.getUserId()));
        return CommonResVo.success(userAccount);
    }
}

这里应用的是 service,和 mapper 的应用差不多,性能更全一点。能够看到,在应用时不再须要关怀应该应用哪个数据库,只有用对了表,间接应用就能够。

代码的残缺示例地址:https://gitee.com/dothetrick/…

以上内容属集体学习总结,如有不当之处,欢送在评论中斧正

欢送关注我的公众号查看更多文章:

正文完
 0