本节目标
- 了解多数据源
- 多数据源中如何切换数据源
- 多数据源中实现事务回滚
- 多数据源中集成p6spy
本节项目:在springboot + mybatis plus + 多数据源 + p6spy
多数据源简介
咱们这里说的多数据源特指:dynamic-datasource-spring-boot-starter。他是一个基于springboot的快速集成多数据源的启动器。其最主要的作用就是能方便的切换本地数据源,能在几个数据库中丝滑的切换并且支持几个本地数据源的事务。
文档地址:www.kancloud.cn/tracy5546/d…
集成多数据源
参照gitee.com/mayuanfei/S…下的springboot05项目创建springboot06项目。然后在其基础上进行修改。目标是,既能访问mysql数据库也能访问oracle数据库
1. SpringBoot三板斧之加入依赖
<!-- mysql的jdbc驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<!-- oracle的jdbc驱动 -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.4</version>
</dependency>
<!-- 多数据源 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.6.1</version>
</dependency>
2. SpringBoot三板斧之添加配置
spring:
datasource:
dynamic:
# 性能分析插件(有性能损耗 不建议生产环境使用)
p6spy: true
# 严格模式 匹配不到数据源则报错
strict: true
# 设置主库.也就是默认操作的数据库
primary: mysql
datasource:
# mysql数据源
mysql:
url: jdbc:mysql://192.168.0.1:3306/springboot-demo?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
# oracel数据源1
oracle18:
url: jdbc:oracle:thin:@192.168.0.2:1521/test
username: root
password: 123456
driver-class-name: oracle.jdbc.OracleDriver
hikari:
connectionTestQuery: SELECT 1 FROM DUAL
# oracel数据源2
oracle183:
url: jdbc:oracle:thin:@192.168.0.3:1521/orcl
username: root
password: 123456
driver-class-name: oracle.jdbc.OracleDriver
hikari:
connectionTestQuery: SELECT 1 FROM DUAL
# 全局hikariCP配置
hikari:
# 最大连接池数量
maxPoolSize: 20
# 最小空闲线程数量
minIdle: 10
# 配置获取连接等待超时的时间
connectionTimeout: 30000
# 校验超时时间
validationTimeout: 5000
# 空闲连接存活最大时间,默认10分钟
idleTimeout: 600000
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟
maxLifetime: 1800000
# 连接测试query(配置检测连接是否有效)
connectionTestQuery: SELECT 1
# 多久检查一次连接的活性
keepaliveTime: 30000
注意
由于多数据源集成了p6spy插件,所以这里只要打开这个开关即可
p6spy: true
3. 修改Mapper层类
-
mysql库:由于设置为主库,所以这里的mapper类没有变化。
@Mapper public interface SysUserMapper extends BaseMapper<SysUser> { } -
oracle18
bank表为oracle18数据库中的表,这里的@DS指定的就是对应的数据源
@DS("oracle18") @Mapper public interface BankMapper extends BaseMapper<Bank> { } -
oracle183
mis_log表为oracle183数据库中的表,这里的@DS指定的就是对应的数据源
@DS("oracle183") @Mapper public interface MisLogMapper extends BaseMapper<MisLog> { }
数据源查询测试
public Map<String, Object> testSelect() {
Map<String, Object> result = MapUtil.newHashMap();
// mysql数据源查询
SysUser sysUser = sysUserMapper.selectById(3L);
result.put("userId", sysUser.getUserId());
result.put("userName", sysUser.getUserName());
// oracel18数据源查询
Bank bank = new LambdaQueryChainWrapper<>(this.bankMapper)
.eq(Bank::getBankid, 777L)
.one();
result.put("bankName", bank.getBankname());
// oracel183数据源查询
MisLog misLog = this.misLogMapper.selectById("1664560539193565184");
result.put("operateDate", misLog.getOperation());
return result;
}
测试输出结果:
多数据源事务回滚测试
@Override
@DSTransactional
public void testRollback() {
//mysql 插入
SysUser sysUser = new SysUser();
sysUser.setUserName("老马77");
sysUser.setNickName("老马哥77");
this.sysUserMapper.insert(sysUser);
System.out.println(sysUser);
//18数据库 插入
Bank bank = new Bank();
bank.setBankid("777");
bank.setBankname("测试银行777");
this.bankMapper.insert(bank);
//183数据库 插入
MisLog misLog = new MisLog();
misLog.setId(IdUtil.getSnowflakeNextIdStr());
misLog.setOperation("测试插入777");
this.misLogMapper.insert(misLog);
int i = 1/0;
}
测试结果:
由于出现异常,这里可以看到mysql数据库和两个oracle数据库中的插入操作均无效
代码地址
gitee.com/mayuanfei/S…下的springboot06
记忆印记
- 多数据源切换在service层,和数据源本身的绑定在mapper层。
- 多数据源事务用@DSTransactional