当前位置: 首页 > news >正文

大白话讲解Spring对数据源和事务管理以及多数据源配置

在我们的开发过程中,Springboot项目里面我们会在配置文件里面配置数据库的账号密码以及连接地址,

spring.datasource.url=jdbc:mysql://localhost:3306/primary_db
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

其实这些就已经够了,已经足够让我们的项目启动连接上数据库了,但是往往我们还会配置数据库连接池,

spring.datasource.jdbc-url=jdbc:mysql://localhost:3306/primary_db
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5

Spring就会将这些配置封装到对应的数据源DataSource上,然后事务管理器会以此数据源作为Spring事务管理器里面的数据源,然后此事务管理器操作的所有事务都会对应到该数据源对应的数据库上,JDBCTemplate默认也会绑定到改默认的数据源上,通过jdbcTemplate操作的SQL语句,也都是该数据库中的表和数据。如果框架里面ORM用的是Mybaits也行,也就是下图中的mapper。

Spring多数据源配置

Spring+多数据源+数据库连接池+事务管理器+事务+JDBCTemplate(Demo)

在基于JdbcTemplate的多数据源配置中,加入数据库连接池(如HikariCP)能够提升性能和资源管理效率。Spring Boot默认使用HikariCP作为连接池,我们可以直接在配置文件中指定连接池属性。以下是完整的配置步骤,包括DataSourceJdbcTemplate、事务管理器和连接池的配置:

1. 添加依赖

确保项目中已经引入了Spring JDBC和MySQL驱动的依赖。HikariCP作为Spring Boot默认连接池,会被自动引入:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
</dependency>

2. 配置数据源和连接池属性

application.ymlapplication.properties中配置主数据源和次数据源的连接池属性。这里以application.yml为例:

spring:datasource:primary:url: jdbc:mysql://localhost:3306/primary_dbusername: primary_userpassword: primary_passdriver-class-name: com.mysql.cj.jdbc.Driverhikari:maximum-pool-size: 10          # 最大连接数minimum-idle: 5                # 最小空闲连接数idle-timeout: 30000            # 空闲连接超时时间max-lifetime: 1800000          # 连接最大存活时间connection-timeout: 20000      # 连接超时时间secondary:url: jdbc:mysql://localhost:3306/secondary_dbusername: secondary_userpassword: secondary_passdriver-class-name: com.mysql.cj.jdbc.Driverhikari:maximum-pool-size: 8minimum-idle: 4idle-timeout: 30000max-lifetime: 1800000connection-timeout: 20000

3. 配置多个DataSourceJdbcTemplate

为每个数据源创建独立的DataSource Bean和JdbcTemplate实例,确保DataSource采用HikariDataSource连接池:

import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
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.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;@Configuration
public class DataSourceConfig {// 配置主数据源并启用HikariCP@Bean(name = "primaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.primary")public DataSource primaryDataSource() {return DataSourceBuilder.create().type(com.zaxxer.hikari.HikariDataSource.class).build();}// 配置次数据源并启用HikariCP@Bean(name = "secondaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.secondary")public DataSource secondaryDataSource() {return DataSourceBuilder.create().type(com.zaxxer.hikari.HikariDataSource.class).build();}// 主数据源的JdbcTemplate@Bean(name = "primaryJdbcTemplate")public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {return new JdbcTemplate(dataSource);}// 次数据源的JdbcTemplate@Bean(name = "secondaryJdbcTemplate")public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) {return new JdbcTemplate(dataSource);}// 主数据源的事务管理器@Bean(name = "primaryTransactionManager")public PlatformTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}// 次数据源的事务管理器@Bean(name = "secondaryTransactionManager")public PlatformTransactionManager secondaryTransactionManager(@Qualifier("secondaryDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
}

4. 使用JdbcTemplate和指定事务管理器

在服务类中,通过@Qualifier注解选择正确的JdbcTemplate和事务管理器:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class SomeService {private final JdbcTemplate primaryJdbcTemplate;private final JdbcTemplate secondaryJdbcTemplate;@Autowiredpublic SomeService(@Qualifier("primaryJdbcTemplate") JdbcTemplate primaryJdbcTemplate,@Qualifier("secondaryJdbcTemplate") JdbcTemplate secondaryJdbcTemplate) {this.primaryJdbcTemplate = primaryJdbcTemplate;this.secondaryJdbcTemplate = secondaryJdbcTemplate;}@Transactional("primaryTransactionManager")public void operateOnPrimaryDataSource() {primaryJdbcTemplate.update("INSERT INTO example_table (column1) VALUES (?)", "value1");}@Transactional("secondaryTransactionManager")public void operateOnSecondaryDataSource() {secondaryJdbcTemplate.update("INSERT INTO example_table (column1) VALUES (?)", "value2");}
}

5. 配置完成后的注意事项

  • 优化连接池:调整连接池参数(如maximum-pool-sizeconnection-timeout)以适应应用负载需求。
  • 观察连接池状态:启动应用后检查日志,确保连接池和各个数据源、事务管理器正确初始化。
  • 事务传播设置:在不同数据源之间切换时,可以根据业务需求调整事务传播(如REQUIRES_NEW),确保数据一致性。

这样,通过配置多数据源、连接池和事务管理器,就可以利用JdbcTemplate实现多数据源操作。连接池管理有助于提升应用的资源利用效率和并发性能。

Spring+多数据源+数据库连接池+事务管理器+事务+Mybatis(Demo)

在使用MyBatis替换JdbcTemplate进行多数据源配置时,需要配置多个数据源和会话工厂(SqlSessionFactory)以及对应的事务管理器。MyBatis的多数据源配置可以通过为每个数据源创建独立的SqlSessionFactoryDataSourceTransactionManager来实现。

以下是基于Spring Boot和MyBatis的多数据源配置步骤:

1. 添加依赖

确保引入了MyBatis的依赖和MySQL驱动:

<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.0</version>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
</dependency>

2. 配置数据源和连接池属性

application.ymlapplication.properties中配置主数据源和次数据源的连接池属性:

spring:datasource:primary:url: jdbc:mysql://localhost:3306/primary_dbusername: primary_userpassword: primary_passdriver-class-name: com.mysql.cj.jdbc.Driverhikari:maximum-pool-size: 10minimum-idle: 5idle-timeout: 30000max-lifetime: 1800000connection-timeout: 20000secondary:url: jdbc:mysql://localhost:3306/secondary_dbusername: secondary_userpassword: secondary_passdriver-class-name: com.mysql.cj.jdbc.Driverhikari:maximum-pool-size: 8minimum-idle: 4idle-timeout: 30000max-lifetime: 1800000connection-timeout: 20000

3. 配置DataSourceSqlSessionFactory和事务管理器

SqlSessionFactoryBean 是 MyBatis 提供的一个工厂类,用于创建 SqlSessionFactory 对象。SqlSessionFactory 是 MyBatis 中的核心对象,它负责创建 SqlSession 实例,通过这些实例可以执行数据库操作。

在 Spring 环境中,SqlSessionFactoryBean 可以简化 SqlSessionFactory 的配置和创建过程。通常我们在配置文件中定义 SqlSessionFactoryBean Bean,并且绑定数据源、配置文件、映射文件等信息。SqlSessionFactoryBean 会根据这些配置生成一个 SqlSessionFactory 实例。

SqlSessionFactoryBean 的主要功能和作用,绑定数据源:将 DataSource 注入 SqlSessionFactoryBean,从而让 SqlSessionFactory 使用该数据源进行数据库连接管理。配置 MyBatis 属性:可以通过 SqlSessionFactoryBean 设置 MyBatis 的全局配置属性,例如开启缓存、日志输出级别等。加载 MyBatis 配置文件:支持加载 MyBatis 主配置文件(mybatis-config.xml),其中可以设置 MyBatis 的详细配置。注册别名和插件:可以通过配置别名或插件,让 MyBatis 使用简化的类名(如 @Alias),并增强功能(如 PageHelper 分页插件)。

为每个数据源创建独立的DataSource Bean、SqlSessionFactory和事务管理器:

import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;@Configuration
public class DataSourceConfig {// 主数据源配置@Primary@Bean(name = "primaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.primary")public DataSource primaryDataSource() {return DataSourceBuilder.create().build();}// 次数据源配置@Bean(name = "secondaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.secondary")public DataSource secondaryDataSource() {return DataSourceBuilder.create().build();}// 主数据源的SqlSessionFactory@Primary@Bean(name = "primarySqlSessionFactory")public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);return sessionFactory.getObject();}// 次数据源的SqlSessionFactory@Bean(name = "secondarySqlSessionFactory")public SqlSessionFactory secondarySqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);return sessionFactory.getObject();}// 主数据源的事务管理器@Primary@Bean(name = "primaryTransactionManager")public DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}// 次数据源的事务管理器@Bean(name = "secondaryTransactionManager")public DataSourceTransactionManager secondaryTransactionManager(@Qualifier("secondaryDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
}

4. 配置MapperScan扫描不同数据源的Mapper

使用@MapperScan注解指定每个数据源的SqlSessionFactory,分别扫描不同的Mapper包路径:

// 主数据源的Mapper扫描配置
@Configuration
@MapperScan(basePackages = "com.example.primary.mapper", sqlSessionFactoryRef = "primarySqlSessionFactory")
public class PrimaryMyBatisConfig {
}// 次数据源的Mapper扫描配置
@Configuration
@MapperScan(basePackages = "com.example.secondary.mapper", sqlSessionFactoryRef = "secondarySqlSessionFactory")
public class SecondaryMyBatisConfig {
}

5. 在Service中使用不同的数据源和事务管理器

在Service层中,通过@Transactional注解指定不同的事务管理器,以便切换数据源:

import com.example.primary.mapper.PrimaryMapper;
import com.example.secondary.mapper.SecondaryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class SomeService {private final PrimaryMapper primaryMapper;private final SecondaryMapper secondaryMapper;@Autowiredpublic SomeService(PrimaryMapper primaryMapper, SecondaryMapper secondaryMapper) {this.primaryMapper = primaryMapper;this.secondaryMapper = secondaryMapper;}@Transactional("primaryTransactionManager")public void operateOnPrimaryDataSource() {primaryMapper.insertData("primary data");}@Transactional("secondaryTransactionManager")public void operateOnSecondaryDataSource() {secondaryMapper.insertData("secondary data");}
}

6. 配置完成后的注意事项

  • 优化连接池配置:根据应用负载调整Hikari连接池参数。
  • 事务管理:确保在@Transactional中使用正确的事务管理器来区分数据源。
  • 数据源切换检查:启动应用时查看日志,确认每个DataSourceSqlSessionFactory和事务管理器是否正确初始化。

这样,就可以通过配置MyBatis、数据源、事务管理器和Mapper扫描路径来实现MyBatis的多数据源管理。


http://www.mrgr.cn/news/61063.html

相关文章:

  • 国际数字影像产业园:智慧园区中的创新协作平台
  • java 聚合和规约的区别
  • C++学习,算法
  • 智能化超声波影像分析,优化医疗决策的开源AI解决方案
  • 基于深度学习算法的动物检测系统(含PyQt+代码+训练数据集)
  • 网管平台(进阶篇):网管软件的配置方式
  • 深入理解所有权与借用——借用与生命周期管理
  • OPA548T 数据手册OPA548 高电压、大电流运算放大器芯片
  • 拥抱中国企业数智化周期,IT产业投资切入点何在?
  • python基础(类、实例、属性、方法)
  • 音频翻译怎么操作?亲测实用的4个转换工具,推荐收藏
  • Python字典到JSON字符串的转换
  • 常用方法:枚举类型
  • golang包导入注意事项
  • 山峰为您的设备选择合适的油封
  • IDEA使用正则批量替换(理论上JetBrains全家桶都适用)
  • 基础IO -- 简单封装库(文件操作)
  • CRM客户关系管理系统:全方位提升销售效能的利器
  • 「后人类视角下的哲学思考:技术与人性的新边界」
  • 【modbus协议】libmodbus库移植基于linux平台