【Java】SpringBoot MybatisPlus 连接多数据源(Mysql、SQL Server)
1. 前言
连接多数据源的场景非常多哈,比如读写分离,多业务库报表。
2. 环境准备
- JDK1.8
- Mysql 8.0 (主库)
- SQL Server 2008 R2(老业务系统)
- JetBrains IDEA
- Springboot 2.0.4 (Maven项目)
- MyBatis-Plus 3.5.0
3. 配置步骤
1)pom.xml
由于我使用到了MybatisPlus,所以直接使用MybatisPlus官方推荐的dynamic-datasource-spring-boot-starter
。
其次,用到了SqlServer数据库,所以要增加连接SQLServer的JDBC驱动。(SQL Server 2008 R2对应可以使用8.2.2.jre8版本,我是这么搭配的,供参考)
pom.xml
文件中增加:
<dependencies> <dependency> <groupId>com.baomidougroupId> <artifactId>dynamic-datasource-spring-boot-starterartifactId> <version>3.5.0version> dependency> <dependency> <groupId>com.microsoft.sqlservergroupId> <artifactId>mssql-jdbcartifactId> <version>8.2.2.jre8version> dependency> dependencies>
2)修改application.yml文件
这里是重中之重,这里要配置好。但是也没有那么难。
1. 之前的配置:
spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: Asia/Shanghai datasource: url: jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource
2. 修改后(多数据源)的配置:
spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: Asia/Shanghai datasource: dynamic: primary: master #设置默认的数据源或者数据源组,默认值即为master strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源 datasource: master: url: jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource slave_1: url: jdbc:sqlserver://localhost:1433;DatabaseName=数据库名 username: sa password: sa driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
其他更详细的配置可以参考这个官方文档描述。
可以看到,我把之前的mysql数据库做成了master库,也就是主库,也就是上面primary参数中配置的默认库,如果代码中没有明确指定数据库,默认就是master库。
另外添加了一个slave_1库,slave_1是一个sqlserver库。从名字可以看出来,slave可以有N个库。
4. 多数据源的使用
配置好之后当然就是使用了。
当然,使用起来也非常简单,总的来说就是:
在service层(或使用到的方法上)添加注解@DS(“xxxxxxx”)
先简单看一下我的项目结构(只展示关键结构,其他涉密不展示):
- 项目名称--class="lazy" data-src---main----java-----com.doph.codepro------controllerDophController.java------entityDoph.java------mapperDophMapper.java------serviceDophService.java-------implDophServiceImpl.java
1)entity层
就是简单的实体类,简单写几个字段。@Data注解是lombok的,不知道的可以搜索一下噢~
@Data@TableName("xxx_doph")public class Doph {private static final long serialVersionUID = 1L;@TableIdprivate int id;private String name;private int age;}
2)Mapper层
由于用了mybatisPlus,而且业务都是简单业务,所以这几部分代码量都比较少,不会的可以看一下mybatisplus的官网。
public interface DophMapper extends BaseMapper<Doph>{}
3)Service层
public interface DophService extends IService<Doph>{}
4)Impl层(重)
由于业务都是写在Impl层的,所以根据最小化原则,这里使用@DS
注解。
因为我这个文件中的业务操作都是在slave_1
库中的,所以这里的@DS
注解我直接加在了类上。当然,根据自己的业务,加在方法上也是ok的。
@Servcie@DS("slave_1")public class DophServiceImpl extends ServiceImpl<DophMapper, Doph> implements DophService{}
如果这里的业务是:
从slave_1库中取出slaveList,再从master库中取出masterList,把name相同的条目插入到slave_2库里面去。
那么有可能出现这种情况(以下是伪代码举例):
@Servicepublic DophServiceImpl extends ServiceImpl<DophMapper, Doph> implements DophService{@Autowiredprivate DophMapper dophMapper;@Override@DS("slave_1")private List<Doph> getSlave(){List<Doph> slaveList = new ...;...return slaveList ;}@Override@DS("master")private List<Doph> getMaster(){List<Doph> masterList= new ...;...return masterList;}@Override@DS("slave_2")public void getDiff(){List<Doph> slaveList = getSlave();List<Doph> masterList= getMaster();//循环比较差异for(...){if(slave.name.equals(master.name)){dophMapper.insert(..);}}}}
5)Controller层
@Controller@RequestMapping("/doph/")public class DophController { @Autowired private DophService dophService; @RequestMapping("id1328") @ResponseBody public Doph testGetOneDoph(){ QueryWrapper queryWrapper = new QueryWrapper(); queryWrapper.eq("id",1328); return dophService.getOne(queryWrapper); }}
以上就能完整地输出一个id为1328的Doph Json啦~
5. 结果展示
证明我不是在吹牛逼,当然,里面的数据是一点都不能透露。
后记
之前一直比较害怕多数据源这块。也说不上来原因。当业务达到一定体量之后,或者源于设计之初的规划,多多少少都会碰到多数据源的情况。之前数据库多用Oracle,并且自己也有OCP证书,所以Oracle的DBLink总是解决多数据源的第一选择。今天终于突破了这个小点。其实真的一点都不难,难的是突破自己的心魔。
共勉。
来源地址:https://blog.csdn.net/liu_jiachen/article/details/125205754
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341