内容概述
本文简要介绍下,当我的项目应用多个数据库的时候,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: 600sdbconfig: 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。
- 用于治理数据库的连贯和会话,不同的数据库要创立不同的配置。
- 对应到下面代码中就是
mainDataSource
和mainSqlSessionFactory
,这里应用了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
判断主库中用户是否存在,而后获取用户的账户信息。
@RestControllerpublic 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/...
以上内容属集体学习总结,如有不当之处,欢送在评论中斧正
欢送关注我的公众号查看更多文章: