🎓博主介绍:Java、Python、js全栈开发 “多面手”,精通多种编程语言和技术,痴迷于人工智能领域。秉持着对技术的热爱与执着,持续探索创新,愿在此分享交流和学习,与大家共进步。
📖DeepSeek-行业融合之万象视界(附实战案例详解100+)
📖全栈开发环境搭建运行攻略:多语言一站式指南(环境搭建+运行+调试+发布+保姆级详解)
👉感兴趣的可以先收藏起来,希望帮助更多的人
SpringBoot整合MyBatis实战:多数据源配置避坑指南
一、背景介绍
在实际的项目开发中,经常会遇到需要同时连接多个数据源的情况。例如,业务数据库和日志数据库分离、读写分离等场景。Spring Boot 是一个快速开发框架,MyBatis 是一个优秀的持久层框架,将它们整合并配置多数据源是一项常见的任务,但在配置过程中会遇到一些坑。本文将详细介绍 Spring Boot 整合 MyBatis 实现多数据源配置的步骤,并给出避坑指南。
二、环境准备
2.1 开发工具
- IntelliJ IDEA:一款功能强大的 Java 开发工具。
- Maven:用于项目的依赖管理和构建。
2.2 技术栈
- Spring Boot:版本 2.7.5
- MyBatis:版本 3.5.9
- MySQL:版本 8.0
2.3 创建 Spring Boot 项目
可以使用 Spring Initializr(https://start.spring.io/)快速创建一个 Spring Boot 项目,添加以下依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
三、多数据源配置步骤
3.1 配置数据源信息
在 application.properties 或 application.yml 中配置多个数据源的信息。以 application.yml 为例:
spring:
datasource:
primary:
url: jdbc:mysql://localhost:3306/primary_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
secondary:
url: jdbc:mysql://localhost:3306/secondary_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
3.2 创建数据源配置类
创建两个数据源配置类,分别配置主数据源和从数据源。
import com.zaxxer.hikari.HikariDataSource;
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 javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
@Primary
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
@Bean(name = "secondaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
}
3.3 创建 MyBatis 配置类
为每个数据源创建对应的 MyBatis 配置类,指定 Mapper 接口和 XML 文件的位置。
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "com.example.primary.mapper", sqlSessionFactoryRef = "primarySqlSessionFactory")
public class PrimaryMyBatisConfig {
@Bean(name = "primarySqlSessionFactory")
public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/primary/*.xml"));
return sessionFactory.getObject();
}
}
@Configuration
@MapperScan(basePackages = "com.example.secondary.mapper", sqlSessionFactoryRef = "secondarySqlSessionFactory")
public class SecondaryMyBatisConfig {
@Bean(name = "secondarySqlSessionFactory")
public SqlSessionFactory secondarySqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/secondary/*.xml"));
return sessionFactory.getObject();
}
}
3.4 创建 Mapper 接口和 XML 文件
分别在 com.example.primary.mapper 和 com.example.secondary.mapper 包下创建 Mapper 接口,并在 classpath:mapper/primary 和 classpath:mapper/secondary 目录下创建对应的 XML 文件。
// 主数据源 Mapper 接口
package com.example.primary.mapper;
import com.example.primary.entity.PrimaryEntity;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface PrimaryMapper {
List<PrimaryEntity> selectAll();
}
// 从数据源 Mapper 接口
package com.example.secondary.mapper;
import com.example.secondary.entity.SecondaryEntity;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface SecondaryMapper {
List<SecondaryEntity> selectAll();
}
3.5 创建 Service 层和 Controller 层
创建 Service 层和 Controller 层来调用 Mapper 接口的方法。
// 主数据源 Service 层
package com.example.primary.service;
import com.example.primary.entity.PrimaryEntity;
import com.example.primary.mapper.PrimaryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class PrimaryService {
@Autowired
private PrimaryMapper primaryMapper;
public List<PrimaryEntity> getAll() {
return primaryMapper.selectAll();
}
}
// 从数据源 Service 层
package com.example.secondary.service;
import com.example.secondary.entity.SecondaryEntity;
import com.example.secondary.mapper.SecondaryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SecondaryService {
@Autowired
private SecondaryMapper secondaryMapper;
public List<SecondaryEntity> getAll() {
return secondaryMapper.selectAll();
}
}
// Controller 层
package com.example.controller;
import com.example.primary.service.PrimaryService;
import com.example.secondary.service.SecondaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DataController {
@Autowired
private PrimaryService primaryService;
@Autowired
private SecondaryService secondaryService;
@GetMapping("/primary")
public Object getPrimaryData() {
return primaryService.getAll();
}
@GetMapping("/secondary")
public Object getSecondaryData() {
return secondaryService.getAll();
}
}
四、避坑指南
4.1 数据源配置问题
- 配置文件错误:确保
application.yml或application.properties中的数据源配置信息正确,包括 URL、用户名、密码和驱动类名。 - 数据源类型:建议使用 HikariCP 作为数据源,它是 Spring Boot 默认的数据源,性能较好。
4.2 MyBatis 配置问题
- Mapper 扫描路径:确保
@MapperScan注解中的basePackages属性指定的 Mapper 接口路径正确。 - XML 文件位置:确保
SqlSessionFactory中指定的 XML 文件位置正确,否则会导致 Mapper 方法无法找到对应的 SQL 语句。
4.3 事务管理问题
- 多数据源事务:在多数据源环境下,默认的事务管理器只对主数据源生效。如果需要对多个数据源进行事务管理,可以使用
JtaTransactionManager或Atomikos等分布式事务管理器。
4.4 依赖冲突问题
- 版本冲突:确保 Spring Boot、MyBatis 和 MySQL 驱动等依赖的版本兼容,避免出现版本冲突导致的异常。
五、总结
通过以上步骤,我们可以实现 Spring Boot 整合 MyBatis 的多数据源配置。在配置过程中,需要注意数据源配置、MyBatis 配置、事务管理和依赖冲突等问题。遵循这些避坑指南,可以避免大部分常见的错误,提高开发效率。

1375

被折叠的 条评论
为什么被折叠?



