欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > Spring Boot 实现多数据源配置

Spring Boot 实现多数据源配置

2025/3/17 16:14:22 来源:https://blog.csdn.net/qq_33807380/article/details/145923546  浏览:    关键词:Spring Boot 实现多数据源配置

一、配置流程

在 Spring Boot 中实现多数据源配置通常用于需要连接多个数据库的场景。主要有以下几个步骤:

  1. 配置多个数据源的连接信息。
  2. 定义多个数据源的 Bean。
  3. 为每个数据源配置MyBatis的SqlSessionFactory和事务管理器。
  4. 为每个数据源定义Mapper接口和Mapper XML文件。
  5. 在服务类中使用不同的Mapper接口操作对应的数据源。

二、详细步骤

2.1 添加依赖

首先,在pom.xml中添加MyBatis、数据库驱动和Spring Boot的JDBC依赖。

<dependencies><!-- Spring Boot Starter Web (可选,如果需要使用Web功能) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- MyBatis Starter --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version></dependency><!-- MySQL 驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- Spring Boot Starter JDBC --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency>
</dependencies>
2.2 配置多数据源

在application.properties或application.yml中配置多个数据源的连接信息。

spring:datasource:primary:jdbc-url: jdbc:mysql://localhost:3306/db1username: rootpassword: passworddriver-class-name: com.mysql.cj.jdbc.Driversecondary:jdbc-url: jdbc:mysql://localhost:3306/db2username: rootpassword: passworddriver-class-name: com.mysql.cj.jdbc.Driver
2.3 配置数据源Bean

在Spring Boot中,通过@Configuration类来配置多个数据源的Bean。

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 {// 主数据源@Bean(name = "primaryDataSource")@Primary@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();}
}
2.4 配置MyBatis的SqlSessionFactory和事务管理器

为每个数据源配置独立的SqlSessionFactory和DataSourceTransactionManager。

  • PrimaryDataSourceConfig .java

    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.context.annotation.Primary;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;import javax.sql.DataSource;@Configuration
    @MapperScan(basePackages = "com.example.mapper.primary", sqlSessionFactoryRef = 	"primarySqlSessionFactory")
    public class PrimaryDataSourceConfig {@Bean(name = "primarySqlSessionFactory")@Primarypublic SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);// 设置MyBatis的Mapper XML文件路径sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/primary/*.xml"));return sessionFactory.getObject();}@Bean(name = "primaryTransactionManager")@Primarypublic DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
    }
    
  • SecondaryDataSourceConfig.java

    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 org.springframework.jdbc.datasource.DataSourceTransactionManager;import javax.sql.DataSource;@Configuration
    @MapperScan(basePackages = "com.example.mapper.secondary", sqlSessionFactoryRef = "secondarySqlSessionFactory")
    public class SecondaryDataSourceConfig {@Bean(name = "secondarySqlSessionFactory")public SqlSessionFactory secondarySqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);// 设置MyBatis的Mapper XML文件路径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);}
    }
    
2.5 配置Mapper接口和XML文件

将Mapper接口和XML文件分别放在不同的包中,以区分不同的数据源。

  • 主数据源Mapper接口

    package com.example.mapper.primary;import com.example.model.User;
    import org.apache.ibatis.annotations.Mapper;
    import java.util.List;@Mapper
    public interface PrimaryUserMapper {List<User> findAll();
    }
    
  • 次数据源Mapper接口

    package com.example.mapper.secondary;import com.example.model.Product;
    import org.apache.ibatis.annotations.Mapper;
    import java.util.List;@Mapper
    public interface SecondaryProductMapper {List<Product> findAll();
    }
    
  • 主数据源Mapper XML文件
    在src/main/resources/mapper/primary目录下创建UserMapper.xml:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.example.mapper.primary.PrimaryUserMapper"><select id="findAll" resultType="com.example.model.User">SELECT * FROM user</select>
    </mapper>
    
  • 次数据源Mapper XML文件
    在src/main/resources/mapper/secondary目录下创建ProductMapper.xml:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.example.mapper.secondary.SecondaryProductMapper"><select id="findAll" resultType="com.example.model.Product">SELECT * FROM product</select>
    </mapper>
    
2.6 使用多数据源

在Service中注入对应的Mapper接口,并使用@Transactional注解指定事务管理器。

import com.example.mapper.primary.PrimaryUserMapper;
import com.example.mapper.secondary.SecondaryProductMapper;
import com.example.model.User;
import com.example.model.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;@Service
public class MyService {@Autowiredprivate PrimaryUserMapper primaryUserMapper;@Autowiredprivate SecondaryProductMapper secondaryProductMapper;@Transactional("primaryTransactionManager")public List<User> getUsers() {return primaryUserMapper.findAll();}@Transactional("secondaryTransactionManager")public List<Product> getProducts() {return secondaryProductMapper.findAll();}
}

三、动态数据源切换

如果需要动态切换数据源,可以通过以下步骤:

  1. 动态数据源配置
    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DataSourceContextHolder.getDataSourceType();}
    }
    
  2. 数据源上下文持有者
    public class DataSourceContextHolder {private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();public static void setDataSourceType(String dataSourceType) {contextHolder.set(dataSourceType);}public static String getDataSourceType() {return contextHolder.get();}public static void clearDataSourceType() {contextHolder.remove();}
    }
    
  3. AOP切面
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;@Aspect
    @Component
    public class DataSourceAspect {@Before("@annotation(dataSource)")public void switchDataSource(DataSource dataSource) {DataSourceContextHolder.setDataSourceType(dataSource.value());}
    }
    
  4. 自定义注解
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;@Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface DataSource {String value();
    }
    
  5. 使用动态数据源
    @Service
    public class MyService {@DataSource("primary")public List<User> getUsers() {return primaryUserMapper.findAll();}@DataSource("secondary")public List<Product> getProducts() {return secondaryProductMapper.findAll();}
    }
    

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词