充电桩项目实战:搞定多数据源!

你好,我是田哥

最近,我在对充电桩项目进行微服务升级中,既然是项目升级,难免会遇到各种各样的问题。比如:分布式事务问题、多数据源问题、分布式锁问题等。

43b8c38f58ee753cbcea123d0ea2a30d.jpeg

项目技术栈

  • Spring

  • Spring Boot

  • Spring Cloud Alibaba(Nacos、Gateway、openfeigin、Sentinel)

  • MongoDB+Redis

  • EMQX

  • XXL-JOB

  • RabbitMQ

  • MySQL

  • Atomikos(分布式事务)

  • OSS

项目结构

bf6aebf1f57dbda8de8074b0f4f539e4.png
项目结构

题外话:如果想年后找到更好的工作,推荐看这篇文章

Java后端面试复习规划表,5万字

因为对数据库进行拆分成了多个库,所以,肯定会涉及到比如分布式事务、多数据源等问题,关于分布式事务这采用Atomikos解决的,可以参考之前的文章:

Spring Boot+MyBatis+Atomikos+MySQL(附源码)

分布式事务这里就不聊了,咱们来聊聊多数据源的问题。

多数据源

多数据源的场景通常有:

  • 1:主和从数据库数据源

  • 2:A项目中的数据库和B项目中的数据库

  • 3:A公司数据库和B公司数据库

主和从数据库数据源

主要是用于数据库架构变成了主从结构,通常会使用到注解:@Primary

在Spring框架中,@Primary注解用于指定一个Bean作为主要的候选者,当有多个相同类型的Bean可供选择时,标记为@Primary的Bean将优先被考虑。这在处理多个相同类型Bean的情况时非常有用,特别是在自动装配(Autowiring)时。

例如,假设您有一个接口MyService和两个实现类FirstServiceSecondService,并且都使用@Service注解进行了声明。如果没有使用@Primary注解,在进行自动装配时,Spring会抛出异常,因为无法确定应该选择哪个实现类。但是,如果其中一个实现类使用了@Primary注解,那么Spring就会选择这个Bean进行装配。

以下是一个示例:

@Service
public class FirstService implements MyService {// ...
}@Service
@Primary
public class SecondService implements MyService {// ...
}

在上面的代码中,由于SecondService使用了@Primary注解,因此Spring会自动装配SecondService作为MyService的实现类。

A项目中的数据库和B项目中的数据库

我的充电桩项目中就是这类场景,主要是对充电桩项目拆分了。

下面来看看实现过程。

实现

实现通常分为下面几步:

  • pom配置依赖

  • 配置数据源信息

  • 读取配置信息

  • 使用

pom配置依赖
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version>
</dependency>

跟普通Spring Boot项目集成MyBatis没什么区别。

properties配置
spring.datasource.chargeuser.driverClassName = com.mysql.jdbc.Driver
spring.datasource.chargeuser.jdbc-url = jdbc:mysql://localhost:3306/charge-user?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
spring.datasource.chargeuser.username = root
spring.datasource.chargeuser.password = 123456spring.datasource.chargemarket.driverClassName = com.mysql.jdbc.Driver
spring.datasource.chargemarket.jdbc-url = jdbc:mysql://localhost:3306/charge-market?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
spring.datasource.chargemarket.username = root
spring.datasource.chargemarket.password = 123456

我们这里配置了两个数据源,如果有需要我们可以照着这样配置即可。

数据源信息的装配
@Configuration
@MapperScan(basePackages = "com.tian.mapper.market", sqlSessionTemplateRef  = "marketSqlSessionTemplate")
public class DataSourceMarketConfig {@Bean(name = "marketDataSource")@ConfigurationProperties(prefix = "spring.datasource.chargemarket")public DataSource marketDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "marketSqlSessionFactory")public SqlSessionFactory marketSqlSessionFactory(@Qualifier("marketDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(dataSource);bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/market/*.xml"));return bean.getObject();}@Bean(name = "marketTransactionManager")public DataSourceTransactionManager marketTransactionManager(@Qualifier("marketDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}@Bean(name = "marketSqlSessionTemplate")public SqlSessionTemplate marketSqlSessionTemplate(@Qualifier("marketSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {return new SqlSessionTemplate(sqlSessionFactory);}}

注意:

  • 1:spring.datasource.chargemarket就是我们在properties文件配置数据源信息。

  • 2:com.tian.mapper.market 就是我们需要扫描的mapper

  • 3:classpath:mapper/market/*.xml 扫描的XxxxMapper.xml文件

然后,关于数据源spring.datasource.chargemarket 就这样搞定了,其他mapper的使用和普通mybatis没什么区别。

再来看看spring.datasource.chargeuser数据源的处理,和上面完全一毛一样。

@Configuration
@MapperScan(basePackages = "com.tian.mapper.user", sqlSessionTemplateRef = "userSqlSessionTemplate")
public class DataSourceUserConfig {@Bean(name = "userDataSource")@ConfigurationProperties(prefix = "spring.datasource.chargeuser")public DataSource userDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "userSqlSessionFactory")public SqlSessionFactory userSqlSessionFactory(@Qualifier("userDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(dataSource);bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/user/*.xml"));return bean.getObject();}@Bean(name = "userTransactionManager")public DataSourceTransactionManager userTransactionManager(@Qualifier("userDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}@Bean(name = "userSqlSessionTemplate")public SqlSessionTemplate userSqlSessionTemplate(@Qualifier("userSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {return new SqlSessionTemplate(sqlSessionFactory);}
}

强调一下:项目中使用UserMapper方式并没有什么区别,还是以前Spring Boot+MyBatis方式,所以这里就没有必要在展示相关无用的代码了。

多数据源配置就这么搞定了,学会(废)了吗?

总结

对上面多数据源的配置多一个简单的总结:

  • 1:数据库连接信息不一样(多数据源)

  • 2:扫描的mapper不一样和mapper.xml

  • 3:然后把对应的dataSourceSqlSessionFactoryTransactionManager以及SqlSessionTemplate关联起来。

最后在使用我们的XxxMapper时候就会自动给我们关联起来了相关的SqlSessionFactoryTransactionManager以及SqlSessionTemplat

回复77,免费获取《面试小抄》

推荐

MySQL 开发规范,非常详细,建议收藏!

16k面试中的10个问题

从0开始搭建公司技术栈,yyds

全程面试辅导,保驾护航!

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

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

相关文章

在线摸头GIF生成系统源码

在线摸头GIF在线生成器html网页源码&#xff0c;可以点击选择文件按钮&#xff0c;或者直接将图片拖入&#xff0c;即可生成导出

GPIO中断

1.EXTI简介 EXTI是External Interrupt的缩写&#xff0c;指外部中断。在嵌入式系统中&#xff0c;外部中断是一种用于处理外部事件的机制。当外部事件发生时&#xff08;比如按下按钮、传感器信号变化等&#xff09;&#xff0c;外部中断可以立即打断正在执行的程序&#xff0…

十一、常用API——练习

常用API——练习 练习1 键盘录入&#xff1a;练习2 算法水题&#xff1a;练习3 算法水题&#xff1a;练习4 算法水题&#xff1a;练习5 算法水题&#xff1a; 练习1 键盘录入&#xff1a; 键盘录入一些1~100之间的整数&#xff0c;并添加到集合中。 直到集合中所有数据和超过2…

Qt Excel读写 - QXlsx的安装配置以及测试

Qt Excel读写 - QXlsx的安装配置以及测试 引言一、安装配置二、简单测试 引言 Qt无自带的库处理Excel 文件&#xff0c;但可通过QAxObject 借助COM接口进行Excel的读写1。亦可使用免费的开源第三方库&#xff1a;QXlsx&#xff0c;一个基于Qt库开发的用于读写Microsoft Excel文…

Java中Date时间类的使用

目录 一、java.util.Date实例化介绍 一&#xff09;、Date对象实例化 二&#xff09;设置Date对象指定日期 &#xff1a; 三&#xff09;将日期格式化输出为中文状态 二、方法介绍 三、方法演示 一、java.util.Date实例化介绍 一&#xff09;、Date对象实例化 //使用无参构造…

Day01_变量和数据类型(注释,关键字,标识符,数据类型,字面量,变量,常量,进制,计算机存储单位,Java的基本数据类型的存储范围,计算机如何表示数据)

文章目录 JavaSE_Day01 变量和数据类型学习目标1.1 注释&#xff08;*comment*&#xff09;&#xff08;掌握&#xff09;1.2 关键字&#xff08;*keyword*&#xff09;&#xff08;掌握&#xff09;1.3 标识符( identifier)&#xff08;掌握&#xff09;1.3.1 标识符的命名规则…

如果我要访问一个网址,那么在网络中会有哪些过程

访问一个网址是我们日常网络使用中非常常见的操作&#xff0c;背后涉及到一系列精密而复杂的步骤。这个过程包括DNS解析、建立TCP连接、发起HTTP请求、服务器处理请求、服务器响应、浏览器渲染等环节。在这篇文章中&#xff0c;我们将深入探讨这些步骤&#xff0c;并解释它们在…

JVM 内存模型

1 什么是 JVM 内存模型 JVM 需要使用计算机的内存&#xff0c;Java 程序运行中所处理的对象或者算法都会使用 JVM 的内 存空间&#xff0c;JVM 将内存区划分为 5 块&#xff0c;这样的结构称之为 JVM 内存模型。 2 JVM 为什么进行内存区域划分 随着对象数量的增加&#xff…

“减半倒数80天”!比特币18个月后将飙涨四倍!但多数矿企短期面临亏损?

随着比特币现货ETF的顺利推出&#xff0c;比特币的另一个潜在的催化剂就是即将到来的第四次减半。据Bitcoin Block Half最新数据&#xff0c;目前距离比特币减半仅剩余约80天&#xff0c;预计将在今年4月22日发生&#xff0c;届时&#xff0c;每个区块的比特币奖励将从当前的6.…

常见分类网络的结构

VGG16 图片来自这里 MobilenetV3 small和large版本参数,图片来着这里 Resnet 图片来自这里

PCB设计10条重要布线原则(学习笔记)

文章目录 一、连线精简二、避免走直角线三、差分走线四、蛇形走线五、圆滑走线六、数字与模拟分开七、3W原则八、20H原则九、铜箔承载电流十、过孔承载电流 一、连线精简 尽量用最短的路径去布线 1、可以省资源 2、信号差损少 3、线能不拐弯就不拐弯 4、能不换层就不换层 二…

Modern C++ std::get<n>(tuple)的原理

1. 前言 前面我们讲过std::tuple的实现原理&#xff0c;但没有讲如何取出数据&#xff0c;本节着重讲讲这点。本节与之前的blog有较大关联&#xff0c;如果您没看&#xff0c;这里有链接&#xff0c;链接已按由浅入深排好序&#xff0c;您可以按顺序阅读。如果时间少可以直接看…