本文分享自华为云社区 《实战指南,SpringBoot + Mybatis 如何对接多数据源》,作者:战斧。

在我们开发一些具有综合功能的项目时,往往会碰到一种情况,需要同时连接多个数据库,这个时候就需要用到多数据源的设计。而Spring与Myabtis其实做了多数据源的适配,只需少许改动即可对接多数据源。本期我们就贴近实战,以一个单数据源的Demo为例,讲述将其改为多数据源项目的过程,希望大家能有所体会。

一、数据源的定义

数据源(Data Source)是指数据存储的地方,大多数情况是指数据库,不过文件服务器、传感器、API等也能算数据源,主要是提供了对数据的访问和操作。数据源中存储了所有建立数据库连接的信息。就像通过指定文件名称可以在文件系统中找到文件一样,通过提供正确的数据源名称,你可以找到相应的数据库连接。

二、单数据源配置

因为SpringBoot对数据源有着高度的默认配置,只配置一个数据源时,该数据源会被作为默认,所以对接单数据源其实是非常简单的。如果你的工程采用的yaml格式配置文件,我们仅需做如下配置:

spring:
#数据库连接配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/springtest
username: root
password: root

如果是采用properties配置文件的也是一样的:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springtest
spring.datasource.username=root
spring.datasource.password=root

三、如何配置多数据源

1. 工程层级调整

我们以曾经搭建的工程为原始模板,进行对接多数据源的操作。没看过的可以点此查看: 从零开始,手把手教你搭建Spring Boot后台工程并说明

因为仅变动数据源,所以我们不改动其他层级,仅仅将 mapper 拆为 mapper1 与 mapper2 两部分

2. Spring项目配置

然后我们需要在 application.properties 或者 application.yml 中定义多个数据源:

spring:
#数据库连接配置
datasource1:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3306/springtest2
username: root
password: root
datasource2:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3306/springtest
username: root
password: root

这里有两个细节需要注意:

  • 因为我们决定使用双数据源,所以把数据源的连接配置改成了datasource1 和 datasource2。而不再保留datasource,这样SpringBoot就不再会为我们设定默认数据库
  • 因为我们目前采用的 springBoot2.5.2,默认的连接池为Hikari,该连接池数据源的地址字段为jdbc-url 而非 url。在只有单个数据源时,SpringBoot走默认数据源逻辑为我们把 url 与 jdbc-url 进行映射,保证我们获得数据源。此时我们自己设置的数据源没有进行映射处理,就需要保证字段符合Hikari的要求。否则会出现 java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName 异常

3. 会话配置

仅有配置文件可不行,接下来,我们需要在代码中读取到配置,并建立两个数据源。如下,每个数据源都有隔离的mapper接口、xml文件、会话工厂及会话模板

第一个数据源 如下(示例):

@Configuration
@MapperScan(basePackages = "com.zhanfu.springboot.demo.mapper1", sqlSessionFactoryRef = "sqlSessionFactory1")
public class DataSource1Config { @Bean
@ConfigurationProperties(prefix = "spring.datasource1")
public DataSource dataSource1() {
return DataSourceBuilder.create().build();
} @Bean
public SqlSessionFactory sqlSessionFactory1() throws Exception {
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource1());
String locationPattern = "classpath*:/mapper1/*.xml";
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
return sessionFactoryBean.getObject();
} @Bean(name = "sqlSessionTemplate1")
public SqlSessionTemplate sqlSessionTemplate1(@Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}

配置第二个数据源 DataSource2Config

@Configuration
@MapperScan(basePackages = "com.zhanfu.springboot.demo.mapper2", sqlSessionFactoryRef = "sqlSessionFactory2")
public class DataSource2Config {
@Bean
@ConfigurationProperties(prefix = "spring.datasource2")
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
} @Bean
public SqlSessionFactory sqlSessionFactory2() throws Exception {
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource2());
String locationPattern = "classpath*:/mapper2/*.xml";
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
return sessionFactoryBean.getObject();
} @Bean(name = "sqlSessionTemplate2")
public SqlSessionTemplate sqlSessionTemplate2(@Qualifier("sqlSessionFactory2") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
} @Bean(name = "productMapper")
public ProductMapper mapper2(@Qualifier("sqlSessionTemplate2") SqlSessionTemplate sqlSessionTemplate) throws Exception {
return sqlSessionTemplate.getMapper(ProductMapper.class);
}
}

4. 事务管理器

为两个数据源分别配置自己的事务管理器,如果你的项目里通篇没有方法级别的事务(一个SQL就是一个事务),那不设置这个也不影响,否则还是建议加上。

@Configuration
public class TransactionManagerConfig { @Autowired
private DataSource dataSource1; @Autowired
private DataSource dataSource2; @Bean
public PlatformTransactionManager txManager1() {
return new DataSourceTransactionManager(dataSource1);
} @Bean
public PlatformTransactionManager txManager2() {
return new DataSourceTransactionManager(dataSource2);
}
}

四、验证

我们把两张表拆进两个库中,以两个库模拟两个数据源,使得程序可以同时连接两个库

浏览器输入 http://127.0.0.1:8080/user/findall 查询接口成功

再在浏览器输入 http://127.0.0.1:8080/product/findall 查询第二个库的数据亦成功返回

这样我们就完成了一个工程同时连接两个数据源。

 

总结

经过上述的操作,我们已经成功把项目对接了多数据源。当然,方案肯定不止这一种,后续围绕该问题,我们还会讲解其他方式。但不论是什么方式,主旨都是加深大家对SpringBoot 和 Mybatis的理解,我们曾经梳理过全流程,但只是蜻蜓点水带大家看一遍大体轮廓,并不足以让你精通,后面本专栏将继续深入讲解。

点击关注,第一时间了解华为云新鲜技术~

实战指南,SpringBoot + Mybatis 如何对接多数据源的更多相关文章

  1. springboot+mybatis实现动态切换数据源

    前几天有个需求,需要使用不同的数据源,例如某业务要用A数据源,另一个业务要用B数据源.我上网收集了一些资料整合了一下,虽然最后这个需求不了了之了,但是多数据源动态切换还是蛮好用的,所以记录一下,或许以 ...

  2. Springboot+mybatis+druid 配置多数据源

    项目结构 application.yml配置文件 spring: application: name: service datasource: primary: jdbc-url: jdbc:orac ...

  3. springboot学习笔记:9.springboot+mybatis+通用mapper+多数据源

    本文承接上一篇文章:springboot学习笔记:8. springboot+druid+mysql+mybatis+通用mapper+pagehelper+mybatis-generator+fre ...

  4. springboot+mybatis+通用mapper+多数据源(转载)

    1.数据库准备 数据库表我们在springboot-mybatis数据之外,新建数据库springboot-mybatis2: springboot-mybatis数据库中有t_class表: spr ...

  5. SpringBoot+MyBatis+MySQL读写分离(实例)

    ​ 1. 引言 读写分离要做的事情就是对于一条SQL该选择哪个数据库去执行,至于谁来做选择数据库这件事儿,无非两个,要么中间件帮我们做,要么程序自己做.因此,一般来讲,读写分离有两种实现方式.第一种是 ...

  6. 第九章 springboot + mybatis + 多数据源 (AOP实现)

    在第八章 springboot + mybatis + 多数据源代码的基础上,做两点修改 1.ShopDao package com.xxx.firstboot.dao; import org.spr ...

  7. SpringBoot Mybatis项目中的多数据源支持

    1.概述 有时项目里里需要抽取不同系统中的数据源,需要访问不同的数据库,本文介绍在Springboot+Mybatis项目中如何支持多数据源操作. 有需要的同学可以下载 示例代码 项目结构如下: 2. ...

  8. spring-boot (四) springboot+mybatis多数据源最简解决方案

    学习文章来自:http://www.ityouknow.com/spring-boot.html 配置文件 pom包就不贴了比较简单该依赖的就依赖,主要是数据库这边的配置: mybatis.confi ...

  9. springboot + mybatis + 多数据源

    此文已由作者赵计刚薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验 在实际开发中,我们一个项目可能会用到多个数据库,通常一个数据库对应一个数据源. 代码结构: 简要原理: 1) ...

  10. springboot+mybatis集成多数据源MySQL/Oracle/SqlServer

    日常开发中可能时常会遇到一些这样的需求,业务数据库和第三方数据库,两个或多个数据库属于不同数据库厂商,这时候就需要通过配置来实现对数据库实现多源处理.大致说一下我的业务场景,框架本身是配置的sprin ...

随机推荐

  1. Python的Lambda函数: 一把极简编程的瑞士军刀

    Python中的lambda函数,或者叫匿名函数,是一个极其强大的工具.它以简洁.优雅的语法提供了创建函数的快速方式.在本篇文章中,我们将全方位地深入研究lambda函数的用法和特点,通过理论和实例相 ...

  2. 使用Docker-compose 搭建 Elasticsearch 集群服务

    Elasticsearch是一个开源的分布式搜索和分析引擎,用于处理大规模数据集.它构建在Apache Lucene搜索引擎库之上,提供了强大的全文搜索.实时数据分析和可扩展性. 以下是Elastic ...

  3. ApacheSpark:HowtoBuildandDeployaRealtimeDataProcessinga

    目录 2.1 基本概念解释 2.2 技术原理介绍 2.3 相关技术比较 3.1 准备工作:环境配置与依赖安装 3.2 核心模块实现 3.3 集成与测试 4.1 应用场景介绍 4.2 应用实例分析 4. ...

  4. Oracle将用户权限移植到另一个用户上

    问题描述:往往有些需求,A用户依赖于B用户创建,A用户想要获取B用户的权限,oracle没找到有命令可以直接继承,只能写一些语句来代替 1.查询用户下的权限有哪些 SET PAGESIZE 100 S ...

  5. 浅析switch和if(开发中这两者的优缺点;分析出优缺点在使用就能更确定自己需要使用哪个函数了)

    分析 Switch 相较于 if 的优点 1.switch 执行效率  高于  if 的执行效率 分析: switch是在编译阶段将子函数的地址和判断条件绑定了,只要直接将a的直接映射到子函数地址去执 ...

  6. Windows 环境下Docker 安装伪分布式 Hadoop

    1.环境 Windows 11 Docker 20.0.2 2.拉取镜像 我选择 ubuntu20.04: docker pull ubuntu:20.04 然后我们用命令看一下本地镜像: docke ...

  7. 记一次.Net分布式事务死锁现象以及解决方法

    在本文中,将介绍一次遇到的.Net分布式事务死锁现象以及解决方法.我们将首先了解事务框架的构成,然后分析导致死锁的代码,最后提出解决方法. 事务框架 本次开发框架JMSFramework将分布式事务划 ...

  8. Unity中的RegisterPlugins:深入解析与实用案例

    Unity中的RegisterPlugins:深入解析与实用案例 在Unity游戏开发中,我们经常需要使用第三方插件来实现一些特定的功能.为了让这些插件能够在Unity中正常工作,我们需要对它们进行注 ...

  9. 1.8 运用C编写ShellCode代码

    在笔者前几篇文章中,我们使用汇编语言并通过自定位的方法实现了一个简单的MessageBox弹窗功能,但由于汇编语言过于繁琐在编写效率上不仅要考验开发者的底层功底,还需要写出更多的指令集,这对于普通人来 ...

  10. 快速打开指定目录的cmd

    待解决问题 在使用dirsearch.sqlmap等工具时需要进入对应的目录再打开cmd,现要实现配合utools快速打开对应目录的cmd 解决办法:创捷快捷方式 在对应的文件夹下创建一个快捷方式,对 ...