首页 > 其他分享 >Spring Boot 多数据源配置实战指南:从入门到精通

Spring Boot 多数据源配置实战指南:从入门到精通

时间:2024-11-07 10:17:29浏览次数:5  
标签:em return name 数据源 Boot dataSource Spring public

引言

在现代企业级应用开发中,往往需要同时访问多个数据库来满足不同的业务需求。Spring Boot 作为一个快速开发的框架,提供了非常便捷的方式来配置和管理多数据源。本文将详细介绍如何在 Spring Boot 项目中配置多数据源,并通过实际代码示例展示其应用场景。

一、为什么要配置多数据源?

在实际项目中,配置多数据源的场景非常常见,例如:

  1. 读写分离:为了提高数据库的读写性能,通常会将读操作和写操作分别分配到不同的数据库实例上。
  2. 分库分表:当单个数据库无法满足性能需求时,可以将数据分散到多个数据库中。
  3. 跨部门数据库访问:不同部门或业务线使用独立的数据库,应用需要同时访问多个数据库。
二、Spring Boot 配置多数据源的基本步骤
1. 引入依赖

首先,我们需要在 pom.xml 中引入必要的依赖:

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

2. 配置多数据源

在 application.yml 中配置多个数据源:

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

3. 创建数据源配置类

接下来,我们需要创建两个配置类,分别用于管理主数据源和次数据源:

@Configuration
public class PrimaryDataSourceConfig {

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

    @Primary
    @Bean(name = "primaryEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("primaryDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.primary.domain")
                .persistenceUnit("primary")
                .build();
    }

    @Primary
    @Bean(name = "primaryTransactionManager")
    public PlatformTransactionManager primaryTransactionManager(
            @Qualifier("primaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

@Configuration
public class SecondaryDataSourceConfig {

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

    @Bean(name = "secondaryEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("secondaryDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.secondary.domain")
                .persistenceUnit("secondary")
                .build();
    }

    @Bean(name = "secondaryTransactionManager")
    public PlatformTransactionManager secondaryTransactionManager(
            @Qualifier("secondaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

4. 使用多数据源

在业务代码中,可以通过 @Qualifier 注解指定使用哪个数据源:

@Service
public class UserService {

    @Autowired
    @Qualifier("primaryEntityManagerFactory")
    private EntityManagerFactory primaryEntityManagerFactory;

    @Autowired
    @Qualifier("secondaryEntityManagerFactory")
    private EntityManagerFactory secondaryEntityManagerFactory;

    public void saveUser(User user) {
        EntityManager em = primaryEntityManagerFactory.createEntityManager();
        em.getTransaction().begin();
        em.persist(user);
        em.getTransaction().commit();
        em.close();
    }

    public void saveOrder(Order order) {
        EntityManager em = secondaryEntityManagerFactory.createEntityManager();
        em.getTransaction().begin();
        em.persist(order);
        em.getTransaction().commit();
        em.close();
    }
}

三、高级配置:事务管理与动态数据源选择
1. 事务管理

在多数据源场景下,事务管理变得更加复杂。Spring Boot 提供了 TransactionManager 来管理事务。可以通过 @Transactional 注解来指定哪个数据源的事务:

@Transactional("primaryTransactionManager")
public void saveUser(User user) {
    // 业务逻辑
}

@Transactional("secondaryTransactionManager")
public void saveOrder(Order order) {
    // 业务逻辑
}

2. 动态数据源选择

在某些场景下,我们需要根据业务逻辑动态选择数据源。可以通过自定义 AbstractRoutingDataSource 来实现:

public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDataSource();
    }
}

然后在配置类中定义动态数据源:

@Bean
public DataSource dynamicDataSource() {
    DynamicDataSource dynamicDataSource = new DynamicDataSource();
    Map<Object, Object> targetDataSources = new HashMap<>();
    targetDataSources.put("primary", primaryDataSource());
    targetDataSources.put("secondary", secondaryDataSource());
    dynamicDataSource.setTargetDataSources(targetDataSources);
    dynamicDataSource.setDefaultTargetDataSource(primaryDataSource());
    return dynamicDataSource;
}

最后,在业务代码中通过线程上下文切换数据源:

public class DataSourceContextHolder {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    public static void setDataSource(String dataSource) {
        contextHolder.set(dataSource);
    }

    public static String getDataSource() {
        return contextHolder.get();
    }

    public static void clearDataSource() {
        contextHolder.remove();
    }
}

四、总结

通过本文的详细介绍,我们了解了在 Spring Boot 项目中配置多数据源的基本步骤和进阶技巧。多数据源配置不仅能够满足复杂的业务需求,还能提高系统的扩展性和性能。希望本文能为你提供实用的参考和指导,帮助你在实际项目中更好地应用多数据源配置。

五、参考资料
  1. [Spring Boot官方文档](https://docs.spring.io/spring-

标签:em,return,name,数据源,Boot,dataSource,Spring,public
From: https://blog.csdn.net/Zyj_0101/article/details/143587637

相关文章

  • 158java ssm springboot基于Hive的大数据高校学生考试分析可视化系统考试评估(源码+文
         文章目录系列文章目录前言一、详细视频演示二、项目部分实现截图三、技术栈后端框架springboot前端框架vue持久层框架MyBaitsPlus系统测试四、代码参考源码获取前言......
  • 156java ssm springboot基于hive的大数据安顺旅游景点数据分析可视化系统旅游门票(源码
        文章目录系列文章目录前言一、详细视频演示二、项目部分实现截图三、技术栈后端框架springboot前端框架vue持久层框架MyBaitsPlus系统测试四、代码参考源码获取前言......
  • 【日常记录】解包android vendor_boot.img和vendor_boot-debug.img
    查看文件类型:$filevendor_boot.imgvendor_boot.img:data$filevendor_boot-debug.imgvendor_boot-debug.img:dataunpack_bootimg用法:$./unpack_bootimg-husage:unpack_bootimg[-h]--boot_imgBOOT_IMG[--outOUT][--format{info,mkbootimg}][-0]Unpacks......
  • springboot+vue新闻微信小程序 毕业设计源码06401
    摘要在数字化浪潮的推动下,我们紧跟时代步伐,借助SpringBoot强大的后端开发能力和Vue.js前端框架的灵活性,结合微信小程序的广泛用户基础,精心打造了一款新颖的新闻微信小程序。这款小程序不仅提供了实时、便捷的新闻资讯服务,还通过其用户友好的界面和丰富的社交功能,为用户带......
  • 基于springboot框架在线生鲜商城推荐系统 java实现个性化生鲜/农产品购物商城推荐网站
    基于springboot框架在线生鲜商城推荐系统java实现个性化生鲜/农产品购物商城推荐网站爬虫、数据分析、排行榜基于协同过滤算法推荐、基于流行度热点推荐、平均加权混合推荐机器学习、大数据、深度学习OnlineShopRecommendEx一、项目简介1、开发工具和使用技术IDEA,jdk......
  • SpringCloudGateway网关服务实现文件上传功能
    @目录说明SpringBoot和SpringCloudGateway项目区别说明1.SpringBoot的成功案例文件上传代码pom前端代吗Controller代码重点在:@RequestParam("file00")MultipartFilefile2.SpringCloudGateway的成功案例文件上传代码Controller代码网上其他方案其他方案1:配置filter其他方案2:配......
  • SpringBoot获取文件将要上传的IP地址
    说明:有的项目会涉及文件上传,比如“更换logo业务”,或者“自定义任务上传脚本等业务”都会涉及上传,而有的项目上传成功后找不到上传地址,所以需要打印IP,方便用户知晓上传的精确地址,下面封装了一个IPv4工具类(因为是拷贝现成代码其中会有某些参数未注释,不知道啥意思,敬请谅解!)IPv4......
  • 基于SpringBoot+Vue的名城小区物业管理系统设计与实现毕设(文档+源码)
            目录一、项目介绍二、开发环境三、功能介绍四、核心代码五、效果图六、源码获取:        大家好呀,我是一个混迹在java圈的码农。今天要和大家分享的是一款基于SpringBoot+Vue的名城小区物业管理系统,项目源码请点击文章末尾联系我哦~目前有各类......
  • 个人练习前端技术使用Bootstrap、JQuery、thymeleaf
    说明:本代码只是为了本人练习前后端联动技术,包含html,jquery,thymeleaf模板、ajax请求及后端功能联动,方便自己查找及使用。@目录代码场景场景1.table批量查询功能(有默认值),点击"查询最新数据"从后台查询覆盖默认显示的数据场景2.新增,点击“新建”显示form表单,提交成功后隐藏form表......
  • 七、Spring Boot集成Spring Security之前后分离认证最佳实现
    一、SpringBoot集成SpringSecurity专栏一、SpringBoot集成SpringSecurity之自动装配二、SpringBoot集成SpringSecurity之实现原理三、SpringBoot集成SpringSecurity之过滤器链详解四、SpringBoot集成SpringSecurity之认证流程五、SpringBoot集成SpringSecu......