Springboot 项目配置多数据源

Springboot 项目配置多数据源

基础环境

java8、springboot2.2.13、mybatis、mysql5.x、oracle

项目配置

1.application.yml

spring:datasource:mysql1:username: abcpassword: 123456url: jdbc:mysql://127.0.0.1:3306/panda?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=falsedriver-class-name: com.mysql.cj.jdbc.Driver# 使用druid数据源type: com.alibaba.druid.pool.DruidDataSourceoracle1:url: jdbc:oracle:thin:@127.0.0.1:1521:oracleusername: defaultpassword: 123456driver-class-name: oracle.jdbc.driver.OracleDriver# 使用druid数据源type: com.alibaba.druid.pool.DruidDataSource

2.数据源配置
有三个注意点,其一是 @Primary 作用是标记哪个是主数据源(默认不指定数据源时会调用的数据源);其二是 basePackages 配置的是实际mapper路径,不同数据源路径不能混淆;其三是 setMapperLocations 配置的路径要加上 “classpath:” 前缀,才能找到对应包下的 .xml 文件。

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;import javax.sql.DataSource;@Configuration
public class AllDataSourceConfig {@Bean(name = "safeDrivingDataSource")@ConfigurationProperties(prefix = "spring.datasource.mysql1") // application.yml 中对应属性的前缀@Primarypublic DataSource safeDrivingDataSource() {return DataSourceBuilder.create().type(com.alibaba.druid.pool.DruidDataSource.class).build();}@Bean(name = "emmpAppDataSource")@ConfigurationProperties(prefix = "spring.datasource.oracle1")public DataSource emmpappDataSource() {return DataSourceBuilder.create().type(com.alibaba.druid.pool.DruidDataSource.class).build();}}import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;import javax.sql.DataSource;@Configuration
@MapperScan(basePackages = "com.emmp.safedriving.dao.mapper.ds1", sqlSessionFactoryRef = "safeDrivingSqlSessionFactory")
public class SafeDrivingDataSourceConfig {@Bean("safeDrivingSqlSessionFactory")@Primarypublic SqlSessionFactory sqlSessionFactory(@Qualifier("safeDrivingDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();org.apache.ibatis.session.Configuration mybatisConfig = new org.apache.ibatis.session.Configuration();mybatisConfig.setLazyLoadingEnabled(true);mybatisConfig.setAggressiveLazyLoading(false);mybatisConfig.setMapUnderscoreToCamelCase(true);sqlSessionFactoryBean.setConfiguration(mybatisConfig);sqlSessionFactoryBean.setDataSource(dataSource);sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:com/emmp/safedriving/dao/mapper/ds1/xml/*.xml"));return sqlSessionFactoryBean.getObject();}@Bean("safeDrivingDataSourceTransactionManager")@Primarypublic DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("safeDrivingDataSource") DataSource dataSource){return new DataSourceTransactionManager(dataSource);}@Bean(name = "safeDrivingSqlSessionTemplate")@Primarypublic SqlSessionTemplate sqlSessionTemplate(@Qualifier("safeDrivingSqlSessionFactory") SqlSessionFactory sqlSessionFactory){return new SqlSessionTemplate(sqlSessionFactory);}}import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;import javax.sql.DataSource;@Configuration
@MapperScan(basePackages = "com.emmp.safedriving.dao.mapper.ds2", sqlSessionFactoryRef = "emmpAppSqlSessionFactory")
public class EmmpAppDataSourceConfig {@Bean("emmpAppSqlSessionFactory")public SqlSessionFactory sqlSessionFactory(@Qualifier("emmpAppDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();org.apache.ibatis.session.Configuration mybatisConfig = new org.apache.ibatis.session.Configuration();mybatisConfig.setLazyLoadingEnabled(true);mybatisConfig.setAggressiveLazyLoading(false);mybatisConfig.setMapUnderscoreToCamelCase(true);sqlSessionFactoryBean.setConfiguration(mybatisConfig);sqlSessionFactoryBean.setDataSource(dataSource);sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:com/emmp/safedriving/dao/mapper/ds2/xml/*.xml"));return sqlSessionFactoryBean.getObject();}@Bean("emmpAppDataSourceTransactionManager")public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("emmpAppDataSource") DataSource dataSource){return new DataSourceTransactionManager(dataSource);}@Bean(name = "emmpAppSqlSessionTemplate")public SqlSessionTemplate sqlSessionTemplate(@Qualifier("emmpAppSqlSessionFactory") SqlSessionFactory sqlSessionFactory){return new SqlSessionTemplate(sqlSessionFactory);}
}

3.启动类配置
不需要再添加 @MapperScan

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,  // 排除默认数据源配置DataSourceTransactionManagerAutoConfiguration.class,  // 排除默认事务管理器MybatisAutoConfiguration.class  // 排除 MyBatis 默认配置}
)

4.mapper 定义示例

// 映射对象定义
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;import java.time.LocalDate;
import java.time.LocalDateTime;@Data
@Builder
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class DriverInfo {private Long id;private String driverName;}import org.apache.ibatis.annotations.Mapper;import java.util.List;@Mapper
public interface DriverInfoMapper {List<DriverInfo> queryAll();List<DriverInfo> queryByCellphone(String cellphone);}

对应 DriverInfoMapper.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.emmp.safedriving.dao.mapper.ds2.DriverInfoMapper"><resultMap id="entity" type="com.emmp.safedriving.dao.entity.DriverInfo"><result property="id" column="ID"/><result property="driverName" column="DRIVERNAME"/></resultMap><select id="queryAll" resultMap="entity">SELECT * FROM DRIVER_INFO</select><select id="queryByCellphone" resultMap="entity">SELECT * FROM DRIVER_INFOWHERE CELLPHONE = #{cellphone}ORDER BY ID DESC</select></mapper>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/93863.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/93863.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32_0001 KEILMDK V5.36 编译一个STM32F103C8T6说core_cm3.h文件找不到以及编译器版本不匹配的解决办法

KEILMDK V5.36 编译一个STM32F103C8T6说core_cm3.h文件找不到的解决办法利用KEILMDK V5.36 编译一个STM32F103C8T6说core_cm3.h文件找不到。主要错误信息如下D:/stm32studio/Armmdk/Packs/Keil/STM32F1xx_DFP/2.4.1/Device/Include\stm32f10x.h(486): error: core_cm3.h file n…

基于Transformer的机器翻译——训练篇

前言 还在为机器翻译模型从理论到落地卡壳&#xff1f;系列博客第三弹——模型训练篇强势登场&#xff0c;手把手带你走完Transformer中日翻译项目的最后关键一步&#xff01; 前两期我们搞定了数据预处理&#xff08;分词、词表构建全流程&#xff09;和模型搭建&#xff08…

智能编程中的智能体与 AI 应用:概念、架构与实践场景

一、智能体&#xff08;Intelligent Agent&#xff09;在编程中的定义与架构1. 智能体的核心概念 智能体是指在特定环境中能够自主感知、决策并执行动作的软件实体&#xff0c;具备以下特征&#xff1a;自主性&#xff1a;无需人工干预即可根据环境变化调整行为。交互性&#x…

数组实现各类数据结构

目录 一、数组实现单链表 二、数组实现双链表 三、数组实现栈 四、数组模拟队列 五、数组模拟单调栈 六、数组模拟单调队列&#xff08;滑动窗口&#xff09; 七、数组模拟堆 一、数组实现单链表 #include<iostream> #include<algorithm> #include<cstr…

数据处理与统计分析 —— apply自定义函数

目录 一、向量化与伪向量化 1、向量化 2、np.vectorize 伪向量化&#xff08;特定场景&#xff09; 3、apply&#xff08;自定义函数&#xff09; 二、apply函数 1、对series中使用apply 2、对dataframe中使用apply 3、apply函数案例-泰坦尼克号数据集] 数据集下载链接&#xf…

如何有效利用大语言模型来智能加速产业联盟的产业链转化路径?

观点作者&#xff1a;科易网AI技术转移研究院在科技创新浪潮席卷全球的今天&#xff0c;科技成果转化已成为衡量一个国家创新能力的重要标志。然而&#xff0c;一项权威调查显示&#xff0c;我国科技成果转化率不足30%&#xff0c;大量有价值的创新成果仍停留在实验室阶段&…

视频加水印 视频加水印软件 视频加动态水印

如果你有一个视频&#xff0c;你想给他加一个水印&#xff0c;那么你可以使用这个工具&#xff0c;准备好你的视频和水印。水印一般采用PNG&#xff0c;打开这个工具&#xff0c;把你的视频和水印拖进这个方框当中。视频限制是MP4&#xff0c;水印限制是PNG&#xff0c;它可以把…

面向DeepSeek chat coding实录(二)

向DeepSeek的提问 帮我设计以下两个python class Span 属性&#xff1a; hash值&#xff08;在init函数中通过时间初始化&#xff09; 创建时间&#xff1a;时间&#xff08;在init函数中通过时间初始化&#xff09; 结束时间&#xff1a;时间&#xff08;可选&#xff0c;默认…

Hi3516CV610-00S 海思SOC芯片 可申请开发资料

1.1 概述Hi3516CV610 是一颗应用在安防市场的 IPC SoC。在开放操作系统、新一代视频编解码标准、网络安全和隐私保护、人工智能方面引领行业发展&#xff0c;主要面向室内外场景下的枪机、球机、半球机、海螺机、枪球一体机、双目长短焦机等产品形态&#xff0c;打造极具竞争力…

算法题Day4

目录 13. 练习13 : 整数十位 14. 练习14 : 时间转换 15. 练习15 : 小雨的游泳时间 13. 练习13 : 整数十位 解题方法: #include <iostream> using namespace std; int a; int main() {cin >> a;cout << a % 100 / 10 << endl;return 0; } 14. 练习…

加速你的故障排查:使用 Elasticsearch 构建家电手册的 RAG 应用

作者&#xff1a;来自 Elastic Alessandro Brofferio 学习如何使用 Elasticsearch 构建 RAG 应用&#xff0c;轻松排查你的家电问题。 想要获得 Elastic 认证吗&#xff1f;来看看下一次 Elasticsearch 工程师培训什么时候开始吧&#xff01; Elasticsearch 拥有大量新功能&am…

6.Shell脚本修炼手册---grep命令使用指南

grep 命令&#xff1a;从文本中精准筛选信息的实用指南 文章目录grep 命令&#xff1a;从文本中精准筛选信息的实用指南一、什么是 grep&#xff1f;为什么要用它&#xff1f;二、grep 基本语法三、常用选项详解&#xff08;附实例&#xff09;&#xff08;一&#xff09;模式选…

Python day51

浙大疏锦行 Python day51 复习日&#xff0c;DDPM class DenoiseDiffusion():def __init__(self, eps_model: nn.Module, n_steps: int, device: torch.device):super().__init__()self.eps_model eps_modelself.n_steps n_stepsself.device deviceself.beta torch.linsp…

数据结构:生成 (Generating) 一棵 AVL 树

目录 搭建“创世”的舞台 注入序列&#xff0c;观察演化 注入 10 注入 20 注入 30 注入 40 注入 50 注入 25 再次审视 上一讲&#xff0c;我们已经从最根本的逻辑出发&#xff0c;推导出了 AVL 树失衡时所必需的修复操作——旋转 (Rotation)。 现在&#xff0c;我们将…

github 上传代码步骤

登录GitHub → 点击右上角 ​​ → New Repository​​。填写仓库名称&#xff08;建议与本地项目同名&#xff09;&#xff0c;选择 ​​Public/Private​​。​​关键&#xff1a;不要勾选​​ “Initialize with README”&#xff08;避免与本地仓库冲突&#xff09;。点击 …

陪诊小程序系统开发:开启智慧就医新时代

在数字化浪潮的推动下&#xff0c;智慧医疗正逐渐成为现实。陪诊小程序系统的开发&#xff0c;作为智慧医疗领域的一次重要创新&#xff0c;正以其独特的魅力与优势&#xff0c;引领着就医新时代的到来。它不仅改变了传统就医模式&#xff0c;更以科技的力量&#xff0c;让医疗…

朝花夕拾(七)--------从混淆矩阵到分类报告全面解析​

目录 ​​机器学习模型评估指南&#xff1a;从混淆矩阵到分类报告全面解析​​ ​​1. 引言​​ ​​2. 混淆矩阵&#xff1a;模型评估的基石​​ ​​2.1 什么是混淆矩阵&#xff1f;​​ 2.2二分类问题的混淆矩阵 ​​二分类场景下的具体案例​ ​分析案例: 1.​​案例…

Python读取和设置PNG图片的像素值

在Python中&#xff0c;可以使用Pillow库或OpenCV库来读取和写入PNG图片的像素值。以下是两种方法的详细说明&#xff1a;1. 使用Pillow库Pillow是Python中常用的图像处理库&#xff0c;支持多种图像格式&#xff0c;包括PNG。读取像素值from PIL import Imageimg Image.open(…

SkyWalking + Elasticsearch8 容器化部署指南:国内镜像加速与生产级调优

SkyWalking Elasticsearch8 Docker 部署文档本文提供在 Ubuntu 服务器上&#xff0c;使用 Docker Compose 部署 SkyWalking&#xff08;OAPUI&#xff09;与 Elasticsearch 8 的完整步骤&#xff0c;数据/日志落地到 /media/disk2 前置条件 Ubuntu&#xff0c;已具备 sudo 权限…

有符号和无符号的区别

有符号&#xff08;Signed&#xff09;和无符号&#xff08;Unsigned&#xff09;是计算机编程中用来描述整数数据类型能否表示负数的两个概念。它们的主要区别在于能否表示负数以及数值的表示范围。以下是它们的核心区别&#xff1a;1. 能否表示负数有符号&#xff08;Signed&…