SpringBoot整合MyBatis实战:多数据源配置避坑指南

🎓博主介绍: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.propertiesapplication.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.mappercom.example.secondary.mapper 包下创建 Mapper 接口,并在 classpath:mapper/primaryclasspath: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.ymlapplication.properties 中的数据源配置信息正确,包括 URL、用户名、密码和驱动类名。
  • 数据源类型:建议使用 HikariCP 作为数据源,它是 Spring Boot 默认的数据源,性能较好。

4.2 MyBatis 配置问题

  • Mapper 扫描路径:确保 @MapperScan 注解中的 basePackages 属性指定的 Mapper 接口路径正确。
  • XML 文件位置:确保 SqlSessionFactory 中指定的 XML 文件位置正确,否则会导致 Mapper 方法无法找到对应的 SQL 语句。

4.3 事务管理问题

  • 多数据源事务:在多数据源环境下,默认的事务管理器只对主数据源生效。如果需要对多个数据源进行事务管理,可以使用 JtaTransactionManagerAtomikos 等分布式事务管理器。

4.4 依赖冲突问题

  • 版本冲突:确保 Spring Boot、MyBatis 和 MySQL 驱动等依赖的版本兼容,避免出现版本冲突导致的异常。

五、总结

通过以上步骤,我们可以实现 Spring Boot 整合 MyBatis 的多数据源配置。在配置过程中,需要注意数据源配置、MyBatis 配置、事务管理和依赖冲突等问题。遵循这些避坑指南,可以避免大部分常见的错误,提高开发效率。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fanxbl957

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值