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

springboot mybatis-plus 集成多数据源

在 Spring Boot 项目中集成 MyBatis-Plus 并配置多数据源,可以按照以下步骤进行。这个示例将展示如何配置两个数据源,并确保每个数据源都有自己对应的 SqlSessionFactory 和事务管理器。

1. 添加依赖

首先,在你的 pom.xml 文件中添加必要的依赖项:

<dependencies>
    <!-- Spring Boot Starter Data JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- MyBatis-Plus Boot Starter -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>最新版本号</version>
    </dependency>

    <!-- MySQL Connector Java (根据实际使用的数据库选择) -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>

    <!-- HikariCP (Spring Boot 默认的连接池) -->
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
    </dependency>
</dependencies>

2. 配置文件设置

在 application.yml 中配置两个数据源的相关信息:

spring:
  datasource:
    primary:
      url: jdbc:mysql://localhost:3306/primary_db?useUnicode=true&characterEncoding=utf-8&useSSL=false
      username: root
      password: password
      driver-class-name: com.mysql.cj.jdbc.Driver
    secondary:
      url: jdbc:mysql://localhost:3306/secondary_db?useUnicode=true&characterEncoding=utf-8&useSSL=false
      username: root
      password: password
      driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 启用SQL日志输出
  mapper-locations: classpath:/mapper/*.xml # Mapper XML文件位置

3. 数据源配置类

创建两个配置类来分别配置主数据源和次数据源及其相关的 SqlSessionFactory 和事务管理器。

主数据源配置 (PrimaryDataSourceConfig.java)

import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
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.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = "com.hieasy.e3.mapper.primary", sqlSessionFactoryRef = "primarySqlSessionFactory")
public class PrimaryDataSourceConfig {

    @Primary
    @Bean(name = "primaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "primarySqlSessionFactory")
    public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        // 添加MyBatis-Plus插件(如分页插件)
        sessionFactory.setPlugins(new Interceptor[]{new PaginationInterceptor()});
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:mapper/primary/*.xml"));
        return sessionFactory.getObject();
    }

    @Primary
    @Bean(name = "primaryTransactionManager")
    public DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

次数据源配置 (SecondaryDataSourceConfig.java)

import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
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.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = "com.hieasy.e3.mapper.secondary", sqlSessionFactoryRef = "secondarySqlSessionFactory")
public class SecondaryDataSourceConfig {

    @Bean(name = "secondaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "secondarySqlSessionFactory")
    public SqlSessionFactory secondarySqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        // 添加MyBatis-Plus插件(如分页插件)
        sessionFactory.setPlugins(new Interceptor[]{new PaginationInterceptor()});
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:mapper/secondary/*.xml"));
        return sessionFactory.getObject();
    }

    @Bean(name = "secondaryTransactionManager")
    public DataSourceTransactionManager secondaryTransactionManager(@Qualifier("secondaryDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

3.1  关键配置说明

1. 使用 MybatisSqlSessionFactoryBean 而非默认工厂
  • 原因:MyBatis-Plus 的功能(如默认方法)依赖其自定义的 SqlSessionFactory

  • 错误示例:使用原生 SqlSessionFactoryBean 会导致插件失效。

2. 指定独立的Mapper包路径
  • 通过 @MapperScan(basePackages = "包路径", sqlSessionFactoryRef = "工厂Bean名称") 确保每个数据源的Mapper绑定到正确的工厂。

  • 包路径分离:将不同数据源的Mapper接口分别放在不同的包中(如 com.example.mapper.db1 和 com.example.mapper.db2)。

3. 添加MyBatis-Plus插件
  • 在 SqlSessionFactory 中注入插件(如分页插件、乐观锁插件),否则分页等增强功能失效:

 

4. Mapper 接口定义

确保为每个数据源定义的 Mapper 接口位于正确的包下,并继承 BaseMapper。

主数据源 Mapper 示例 (PrimaryMapper.java)

package com.hieasy.e3.mapper.primary;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hieasy.e3.entity.PrimaryEntity;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface PrimaryMapper extends BaseMapper<PrimaryEntity> {
}

次数据源 Mapper 示例 (SecondaryMapper.java)

package com.hieasy.e3.mapper.secondary;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hieasy.e3.entity.SecondaryEntity;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface SecondaryMapper extends BaseMapper<SecondaryEntity> {
}

5. 使用示例

在服务层或控制器中使用这些 Mapper 进行操作时,请确保正确注入它们:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MultiDataSourceService {

    private final PrimaryMapper primaryMapper;
    private final SecondaryMapper secondaryMapper;

    @Autowired
    public MultiDataSourceService(PrimaryMapper primaryMapper, SecondaryMapper secondaryMapper) {
        this.primaryMapper = primaryMapper;
        this.secondaryMapper = secondaryMapper;
    }

    @Transactional("primaryTransactionManager")
    public void operateOnPrimary() {
        // 对主数据源的操作
    }

    @Transactional("secondaryTransactionManager")
    public void operateOnSecondary() {
        // 对次数据源的操作
    }
}

6. 避免自动配置冲突

若手动配置多数据源,需排除Spring Boot的默认数据源自动配置:

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

常见问题排查

  1. 错误提示 Invalid bound statement (not found)

    • 检查Mapper接口的包路径是否在 @MapperScan 中正确指定。

    • 确认XML映射文件(若有)路径是否在配置中指定。

  2. 分页/乐观锁失效

    • 检查是否在 SqlSessionFactory 中添加了对应插件。

  3. 事务不生效

    • 确保在方法上使用 @Transactional(transactionManager = "db1TransactionManager") 指定事务管理器。

相关文章:

  • GF1 遥感影像镶嵌拼接
  • C++ 多态
  • 2.5 使用注解进行单元测试详解
  • 【vue3】实现pdf在线预览的几种方式
  • 论软件评估方法
  • rv1103b编译opencv
  • 家里装修想用投影仪,如何选择?装修中应该注意什么?
  • 浮点数二分
  • 数智化的力量:柏强制药构建医药高质量发展的新引擎
  • 场外个股期权下单后多久成交?场外个股期权对投资组合的影响
  • 《pyqt+open3d》第三章——icp配准点对面——稳健性提升
  • 【前端框架】Vue3 中 `setup` 函数的作用和使用方式
  • 【Elasticsearch】Token Graphs
  • 【LeetCode】739. 每日温度
  • rust学习二、入门之运行单个脚本
  • vue前端可视化大屏页面适配方案
  • 日本90年代经济泡沫初期是什么情况?
  • 面试经典150题——字典树
  • 深入探索xtquant:账户信息查询的全面指南
  • WPS中如何批量上下居中对齐word表格中的所有文字
  • 学校英语网站栏目名称/广告商对接平台
  • 国内哪个网站做水产比较大/南宁优化网站网络服务
  • 个体户能做网站备案吗/网络推广营销策划方案
  • 烟台城乡建设学校网站/职业培训机构哪家最好
  • 网站做宣传域名什么好/中国企业500强
  • 网站用什么语言/找文网客服联系方式