背景介绍
由于项目业务需要,期望在Springboot2+Mybatis-plus框架下集成多个数据源,实现不同业务数据存储到相应的数据库中。最开始的想法是为每个数据源添加配置类。但是出现了报错:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found),即在mybatis中mapper接口与mapper配置文件在做映射绑定的时候出现问题。经过多次检查代码上并没有发现配置错误的情况(此处如果有解决办法的朋友可以在评论中讨论),因此到Mybatis-plus官网中查找Mybatis-plus框架下集成多个数据源的方法。最后通过集成dynamic-datasource扩展插件实现。
为什么需要多数据源集成?
- 不同的业务涉及的表位于不同的数据库
- 主库和从库分离(读写分离)
- 数据库的分片
- 多租户隔离
所有数据库表结构一致,只是不同客户的数据放在不同数据库中,通过数据库名对不同客户的数据隔离。这种场景有一个典型的叫法:多租户。
实现思路
- 不同的业务涉及的表位于不同的数据库
一般不同的业务会对应不同的服务/模块,因此我们会考虑不同的package去隔离,不同的数据源放在不同的包下的代码中。 - 主库和从库分离(读写分离)
这种场景下我们叫动态数据源,通常方式使用AOP方式拦截+ThreadLocal切换。
实现方法
Mybatis框架下实现
- 逐个数据源添加@Configuration配置类
- AOP实现
在这两种方法中,第一种方法使用的更多。具体的实现方式可以参考文章:blog.csdn.net/tuesdayma/a…
Mybatis-plus框架下实现
Mybatis-plus框架和dynamic-datasource扩展
相较于Mybatis框架,Mybatis-plus框架有众多优点。这就回到了最开始产生的集成问题,导致最后没有使用为每个数据源添加@Configuration配置类的实现方法。
- 快速开发简单的增删改查功能:MyBatis Plus提供了一组CRUD方法,无需手动编写SQL语句,可以快捷地完成常见的增删改查操作。
- 简化业务开发:MyBatis Plus封装了很多常用的数据库操作,提供了便捷的API,减少了开发人员对底层SQL的关注,可以专注于业务逻辑的实现。
- 提高开发效率:MyBatis Plus提供了一些便捷的功能,如分页查询、条件构造器、代码生成等,可以节省开发人员的时间和精力。\
具体实现方法Mybatis-plus官网给出了示例:baomidou.com/pages/a61e1…
本文采用dynamic-datasource扩展插件实现,官方文档:www.kancloud.cn/tracy5546/d…
- 本框架只做 切换数据源 这件核心的事情,并不限制你的具体操作,切换了数据源可以做任何CRUD。
- 配置文件所有以下划线
_分割的数据源 首部 即为组的名称,相同组名称的数据源会放在一个组下
项目中实现
- 引入dynamic-datasource-spring-boot-starter。
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!-- 实现mybatis-plus框架下多数据源配置 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.6.1</version>
</dependency>
- 配置数据源
datasource:
dynamic:
primary: resource #设置默认的数据源或者数据源组,默认值为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
datasource1:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://ip:port/db1?useUnicode=true&characterEncoding=UTF-8
username: xxxxx
password: xxxxx
datasource2:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://ip:port/db2?useUnicode=true&characterEncoding=UTF-8
username: xxxxxx
password: xxxxxx
- 使用 @DS 切换数据源。
@DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解。
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service
@DS("datasource1")
public class TestServiceImpl extends ServiceImpl<TestMapper, Test>
implements TestService{
}