springboot+mybatis配置多数据源实战

2023-11-05

     1.背景说明
     2.配置多数据源步骤
         2.1 项目结构变更
         2.2 添加配置类
         2.3 修改配置文件数据连接配置信息
         2.4 多数据源配置导致@Transactional失效问题

1.背景说明

     一般一个项目中只会连接一个数据库.但是随着需求变更,会要求同一个项目中连接多个数据库,本文就讲一下如何在一个项目中对多个数据库进行连接.本文基于springboot+mybatis介绍如何进行多数据源连接(本文演示配置两个数据库,配置多个同理).

2.配置多数据源步骤

2.1 项目结构变更

     以连接不同的数据库进行分包,db1表示连接数据库database1,db2表示连接database2.项目结构如下:
在这里插入图片描述

2.2添加配置类

/**
 * @ClassName: MultiDataSourceConfig
 * @Desc: 多数据源配置
 * @Author: txm
 * @Date: 2022/12/11 9:59
 **/
@Configuration
public class MultiDataSourceConfig {

	// 创建自定义数据源db1
    @Bean(name = "db1")
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    public DataSource businessDbDataSource() {
        return DataSourceBuilder.create().build();
    }

	// 创建自定义数据源db2
    @Bean(name = "db2")
    @ConfigurationProperties(prefix = "spring.datasource.db2")
    public DataSource newhomeDbDataSource() {
        return DataSourceBuilder.create().build();
    }
}

Db1Config配置类:

@Configuration
// 此处添加项目自定义mapper包路径,支持数组形式,指定SqlSessionFactory ,演示包路径已做修改
@MapperScan(basePackages = {"com.api.db1.order.mapper",
        "com.api.db1.pay.mapper",
        "com.api.db1.user.mapper",
        "com.api.db1.distribution.mapper",
        "com.api.db1.aliyun.mapper" }, sqlSessionFactoryRef = "sqlSessionFactoryDb1")
public class Db1Config {

    @Autowired
    @Qualifier("db1")
    private DataSource dataSourceDb1;


    @Bean
    public SqlSessionFactory sqlSessionFactoryDb1() throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSourceDb1);
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/db1/**/*.xml"));
        // 自定义MyBatis configuration.配置打印和大小写转换
        org.apache.ibatis.session.Configuration personalConfiguration = new org.apache.ibatis.session.Configuration();
        personalConfiguration.setMapUnderscoreToCamelCase(true);
        personalConfiguration.setLogImpl(StdOutImpl.class);
        factoryBean.setConfiguration(personalConfiguration);
        return factoryBean.getObject();
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplateDb1() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactoryDb1());
    }
 /**
     * @Author: txm
     * @Description: 配置事务管理器
     * @Param: [dataSource]
     * @return: org.springframework.jdbc.datasource.DataSourceTransactionManager
     * @Date:  2023/1/31 14:00
     **/
    @Bean(name="db1TransactionManager")
    public DataSourceTransactionManager postgreTransactionManagerGenerate(){
        return new DataSourceTransactionManager(dataSourceDb1);
    }

}

Db2Config配置类:

@Configuration
// 此处添加项目自定义mapper包路径,支持数组形式,指定SqlSessionFactory ,演示包路径已做修改
@MapperScan(basePackages = {"com.api.db2.activityUser.mapper",
"com.api.db2.vote.mapper"}, sqlSessionFactoryRef = "sqlSessionFactoryDb2")
public class Db2Config {
    @Autowired
    @Qualifier("db2")
    private DataSource dataSourceDb2;


    @Bean
    public SqlSessionFactory sqlSessionFactoryDb2() throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSourceDb2);
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/db2/**/*.xml"));
        // 自定义MyBatis configuration.配置打印和大小写转换
        org.apache.ibatis.session.Configuration personalConfiguration = new org.apache.ibatis.session.Configuration();
        personalConfiguration.setMapUnderscoreToCamelCase(true);
        personalConfiguration.setLogImpl(StdOutImpl.class);
        factoryBean.setConfiguration(personalConfiguration);
        return factoryBean.getObject();
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplateDb2() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactoryDb2());
    }
/**
     * @Author: txm
     * @Description: 配置事务管理器
     * @Param: [dataSource]
     * @return: org.springframework.jdbc.datasource.DataSourceTransactionManager
     * @Date:  2023/1/31 14:00
     **/
    @Bean(name="db2TransactionManager")
    public DataSourceTransactionManager postgreTransactionManagerGenerate(){
        return new DataSourceTransactionManager(dataSourceDb2);
    }

}

    说明
    自定义配置类Db1ConfigDb2Config中指定 @MapperScan之后可以将启动类上面的@MapperScan注解进行注释,@MapperScan的作用就是扫描mapper所在的包路径:

// modify by txm 2022/12/12 多数据源改造,包扫描添加到自定义数据源配置类Db1Config、Db2Config中
//@MapperScan("com.**.mapper")
@SpringBootApplication
public class H5Application {
    public static void main(String[] args) {
        SpringApplication.run(H5Application.class, args);
    }
}

    配置类中指定mapper配置文件所在路径,否则会提示:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found),添加内容如下::

factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/db2/**/*.xml"));

    对应的配置文件是(可以进行注释):

mybatis:
     # 配置数据库映射文件 **表示是任意多级目录,适配dao/goods
    mapper-locations: classpath:/mapper/**/**/*.xml

    配置mybatis的日志打印与大小写转换:

 // 自定义MyBatis configuration.配置打印和大小写转换
        org.apache.ibatis.session.Configuration personalConfiguration = new org.apache.ibatis.session.Configuration();
        personalConfiguration.setMapUnderscoreToCamelCase(true);
        personalConfiguration.setLogImpl(StdOutImpl.class);
        factoryBean.setConfiguration(personalConfiguration);

    添加之后配置文件中可以将以下内容进行注释:

mybatis:
     # 配置数据库映射文件 **表示是任意多级目录,适配dao/goods
    mapper-locations: classpath:/mapper/**/**/*.xml
     #spring boot集成mybatis的方式打印sql
    configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
     #spring boot记成mybatis将数据库字段字段转换华成驼峰形式
        map-underscore-to-camel-case: true

2.3 修改配置文件数据连接配置信息

spring:
#数据库信息设置
  datasource:
    db1:   # database1服务器地址
      jdbc-url: jdbc:mysql://xxx.xxx.xx.xx:3308/database1?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&allowMultiQueries=true
      username: ****
      password: ****
      driver-class-name: com.mysql.cj.jdbc.Driver
    db2:  # database2服务器地址 
      jdbc-url: jdbc:mysql://xxx.xxx.xx.xx:3308/database2?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&allowMultiQueries=true
      username: ****
      password: ****
      driver-class-name: com.mysql.cj.jdbc.Driver
      # 配置数据库连接池
      type: com.zaxxer.hikari.HikariDataSource
      hikari:
        minimum-idle: 5  # 最小空闲连接数量
        idle-timeout: 180000 # 单位毫秒,此处设置3分钟,空闲连接存活最大时间,默认600000(10分钟)
        maximum-pool-size: 10 # 连接池最大连接数,默认是10
        auto-commit: true     # 此属性控制从池返回的连接的默认自动提交行为,默认值:true
        pool-name: MyHikariCP  # 连接池名称
        max-lifetime: 1800000 # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
        connection-timeout: 30000  # 数据库连接超时时间,默认30秒,即30000

    注意:要将url替换成jdbc-url,否则会提示以下内容:

java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.

    关于数据库连接类型可以选用springboot默认支持的Hikari,性能会更好!如果对Hikari无配置要求,可以不用添加Hikari相关的配置信息.演示内容中配置了db2的Hikari信息.

2.4 多数据源配置导致@Transactional失效问题

    多数据源改造之后会导致@Transactional失效,处理方案如下:
Db1Config.javaDb2Config.java中需要进行注册对应的事务管理器,已经在刚开始的案例中进行了补充。使用的时候需要根据不同的数据源替换掉默认的事务管理器。
以抽奖接口为例说明:
原接口:

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized DrawVo  luckDraw(LuckDrawDto luckDrawDto) {
		// 忽略业务处理逻辑
}

多数据源事务管理改造之后:

 @Override
    @Transactional(transactionManager = "db2TransactionManager",rollbackFor = Exception.class)
    public synchronized DrawVo  luckDraw(LuckDrawDto luckDrawDto) {
		// 忽略业务处理逻辑
}

    以上是关于springboot中配置多数据源的实战记录,希望对有同样需求的同学有所帮助,感觉有所收获欢迎点赞或是留言!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

springboot+mybatis配置多数据源实战 的相关文章

随机推荐

  • java POI解析获取word文件内容

    1 需要的pom文件依赖
  • 微信小程序一键授权之前勾选协议

    微信小程序授权获取手机号之前勾选我已阅读并同意协议 想要实现的效果 用户点击微信一键注册按钮 如果用户没有勾选协议 就提示请勾选用户协议 如果勾选了 就直接获取微信用户的手机号密文 开始想的是直接在getPhoneNumber 方法中加一个
  • python同时发大量请求_PythonWebServer如何同时处理多个请求

    对于初学Web开发 理解一个web server如何能同事处理多个请求很重要 当然更重要的是 理解你通过浏览器发送的请求web server是怎么处理的 然后怎么返回给浏览器 浏览器才能展示的 我到现在还记得大概在2010年左右 看了tom
  • 高德地图的缩放和位移监听

    最近项目采用高德地图 高德地图的文档 demo都很详细 想实现的功能基本上都有 在项目里有一个功能 是类似根据地图的中心经纬度实现数据请求 为了不无限的请求 所以要分别监听 地图的缩放 地图位移 这里就有一个方法 gadMap setOnC
  • matlab根据成绩划分等级_Excel数据分析必备技能:对数据按范围多条件划分等级的判定套路

    点击右上角 关注 每天免费获取干货教程 职场办公中经常要对数据进行整理和分析 其中等级归类划分是很常用的一种方法 在这个过程中用好Excel公式可以事半功倍 但是还是有很多人不了解在Excel中对数据按范围多条件划分等级的系统思路和方法 所
  • Cover Letter常用范式和模版

    摘自 https zhuanlan zhihu com p 26708261 http muchong com html 201401 6920446 html 1 什么是Cover letter Cover Letter 即投稿信 是论文
  • 深聊测开领域之:测试策略模型有哪些?

    测试模型的分类 1 引言 2 金字塔 2 1 金字塔模型 引入 2 2 金字塔弊端 2 3 金字塔图形 3 冰淇淋 3 1 冰淇淋模型 引入 3 2 冰淇淋模型 优缺点 3 2 1 缺点 3 2 2 优点 3 2 冰淇淋图形 4 冠军杯 4
  • 微信小程序面试题汇总

    HTML篇 CSS篇 JS篇 Vue篇 TypeScript篇 React篇 前端面试题汇总大全 含答案超详细 HTML JS CSS汇总篇 持续更新 前端面试题汇总大全二 含答案超详细 Vue TypeScript React Webpa
  • 环境变量知识点

    环境变量 环境变量 环境变量是用来定义系统运行环境的一些参数 比如说 每一个用户的家目录 echo HOME 还有我们在编写C C 代码的时候 在链接的时候 从来不知道我们的所链接的动态静态库在哪里 但是照样可以链接成功 生成可执行程序 原
  • 不使用采集卡,实现相机手机多机位直播

    背景 因为直播需求 现在想实现使用一台相机和一台手机完成直播的两个机位设定 搜了很多视频都是要购买采集卡 违背了性价比这一原则 搜索半天之后 根据当前的设备完成了任务 硬件材料 苹果手机一部 佳能单反 所需软件 1 OBS 主要是用来集成各
  • 刷脸让商家引入智慧经营实现数字化转型

    移动支付在生活中已经实现了全覆盖 从单一的支付到驱动智慧经营 在数据为王的时代 通过对移动支付数据的深度挖掘 整合成消费大数据 移动支付还在经营上改变商户的效率 从以前柜台结账到如今的自助结账 从人工推荐到大数据的精准推荐 彻底的改变了商户
  • Linux make --强大的编译工具

    用途说明 make命令是一个常用的编译命令 尤其是在开发C C 程序时 它通过Makefile文件中描述的源程序之间的依赖关系来自动进行编译 Makefile文件是按照规定的格式编写的 文件中需要说明如何编译各个源文件并连接生成可执行文件
  • CVE-2020-11444:Nexus Repository Manager 3 远程命令执行漏洞

    读者需知 本文仅供学习使用 由于传播和利用此文所造成的损失均由使用者本人负责 文章作者不为此承担责任 简介 Nexus Repository是一个开源的仓库管理系统 可搭建npm maven等私服 Nexus 3 任意修改admin密码越权
  • Socket错误详解及处理方法

    例如错误代码10061 说明服务器已经找到 但连接被服务器拒绝 连接失败原因可能是 端口号设置错误 2 服务器没有处于监听状态 即ServerSocket gt Active true 3 数据包被服务器端的防火墙过滤掉 附 Socket常
  • Qt 连接、操作数据库(增删改查)

    文章目录 Qt 5 9连接MySQL5 7 32 64位 操作数据库 QSqlQuery类 执行SQL语句 查 浏览结果集方法 增 删 改 事务 Qt 5 9连接MySQL5 7 32 64位 MySQL5 7安装好后将其安装路径lib下
  • Django--ORM 多表查询

    目录 数据准备 正向查询与反向查询 基于对象的跨表查询 正向查询 一对多 多对多 一对一 反向查询 一对多 多对多 一对一 正向查询 反向查询 基于双下线的跨表查询 正向查询 一对一 一对多 多对多 反向查询 一对一 一对多 多对多 双下高
  • Pytorch—模型微调(fine-tune)

    随着深度学习的发展 在大模型的训练上都是在一些较大数据集上进行训练的 比如Imagenet 1k Imagenet 11k 甚至是ImageNet 21k等 但我们在实际应用中 我们自己的数据集可能比较小 只有几千张照片 这时从头训练具有几
  • fatal error: ceres/ceres.h: 没有那个文件或目录

    用ubuntu18跑的loam livox算法 系统报错 In file included from home lisheng catkin ws src loam livox master source laser mapping cpp
  • java面试---IO与NIO

    一 概念 NIO即New IO 这个库是在JDK1 4中才引入的 NIO和IO有相同的作用和目的 但实现方式不同 NIO主要用到的是块 所以NIO的效率要比IO高很多 在Java API中提供了两套NIO 一套是针对标准输入输出NIO 另一
  • springboot+mybatis配置多数据源实战

    1 背景说明 2 配置多数据源步骤 2 1 项目结构变更 2 2 添加配置类 2 3 修改配置文件数据连接配置信息 2 4 多数据源配置导致 Transactional失效问题 1 背景说明 一般一个项目中只会连接一个数据库 但是随着需求变