spring-data-jpa+Alibaba Druid多数据源案例实践

 更新时间:2025年07月14日 09:47:27   作者:勤匠  
本文介绍基于Spring Data JPA与Alibaba Druid配置多数据源的方案,通过定义三个独立数据源、分别设置JPA配置及实体/仓库包,实现订单、用户、详情表的分离管理

spring-data-jpa+Alibaba Druid多数据源

很多情况下,应用需要连接多个数据库,基于此场景,我介绍如何使用spring-data-jpa + Alibaba Druid配置多数据源。

代码量有点大,请耐心:

假设一个场景

数据库服务器IP占用端口
testorders(订单表)192.168.10.313306
demodetail(详情表)192.168.10.323306
trainusers(用户表)192.168.10.333306

pom.xml引入

<!--连接池-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.8</version>
</dependency>
<!--数据库驱动-->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>
<!--spring data jpa-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

application.yaml配置

server:
  port: 8080
spring:
  datasource:
    ds1:
      url: jdbc:mysql://192.168.10.31:3306/test
      username: root
      password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver
    ds2:
      url: jdbc:mysql://192.168.10.33:3306/train
      username: root
      password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver
    ds3:
      url: jdbc:mysql://192.168.10.32:3306/demo
      username: root
      password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver

DataSource配置

为了让spring-data-jpa分别使用这三个库,那么我们需要配置3个datasource

package cn.train.springdruid.config.datasource;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
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 DataSourcesConfig {
    @Bean(name = {"ds1"})
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.ds1")
    public DataSource ds1() {
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        return dataSource;
    }
    @Bean(name = {"ds2"})
    @ConfigurationProperties(prefix = "spring.datasource.ds2")
    public DataSource ds2() {
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        return dataSource;
    }
    @Bean(name = {"ds3"})
    @ConfigurationProperties(prefix = "spring.datasource.ds3")
    public DataSource ds3() {
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        return dataSource;
    }
}

JPA配置

接下来针对每个datasource做单独的JPA配置

ds1的JPA配置

package cn.train.springdruid.config.datasource;

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.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration(value = "ds1JPAConfig")
@EnableJpaRepositories(
        basePackages = "cn.train.springdruid.repositories.ds1",//repository包位置
        entityManagerFactoryRef = "ds1EntityManagerFactory",
        transactionManagerRef = "ds1TransactionManager"
)
public class Ds1JPAConfig {
    @Bean(name = {"ds1TransactionManager"})
    public PlatformTransactionManager ds1TransactionManager(
            @Qualifier("ds1EntityManagerFactory") EntityManagerFactory emf){
        return new JpaTransactionManager(emf);
    }
    @Bean(name = {"ds1EntityManagerFactory"})
    @Primary
    public LocalContainerEntityManagerFactoryBean ds1EntityManagerFactory(
            @Qualifier(value = "ds1") DataSource dataSource,
            JpaVendorAdapter vendorAdapter) {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource);
        entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
        entityManagerFactoryBean.setPackagesToScan("cn.train.springdruid.entities.ds1");// entity包位置
        entityManagerFactoryBean.setJpaProperties(
                new Properties(){{
                    put("hibernate.hbm2ddl.auto", "update");
                    put("hibernate.show_sql", "true");
                    put("hibernate.format_sql", "true");
                }}
        );
        return entityManagerFactoryBean;
    }
}

ds2的JPA配置

package cn.train.springdruid.config.datasource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration(value = "ds2JPAConfig")
@EnableJpaRepositories(
        basePackages = "cn.train.springdruid.repositories.ds2",//repository包位置
        entityManagerFactoryRef = "ds2EntityManagerFactory",
        transactionManagerRef = "ds2TransactionManager"
)
public class Ds2JPAConfig {
    @Bean(name = {"ds2TransactionManager"})
    public PlatformTransactionManager ds2TransactionManager(
            @Qualifier("ds2EntityManagerFactory") EntityManagerFactory emf){
        return new JpaTransactionManager(emf);
    }
    @Bean(name = {"ds2EntityManagerFactory"})
    public LocalContainerEntityManagerFactoryBean ds2EntityManagerFactory(
            @Qualifier(value = "ds2") DataSource dataSource,
            JpaVendorAdapter vendorAdapter) {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource);
        entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
        entityManagerFactoryBean.setPackagesToScan("cn.train.springdruid.entities.ds2");// entity包位置
        entityManagerFactoryBean.setJpaProperties(
                new Properties(){{
                    put("hibernate.hbm2ddl.auto", "update");
                    put("hibernate.show_sql", "true");
                    put("hibernate.format_sql", "true");
                }}
        );
        return entityManagerFactoryBean;
    }
}

ds3的JPA配置

package cn.train.springdruid.config.datasource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration(value = "ds3JPAConfig")
@EnableJpaRepositories(
        basePackages = "cn.train.springdruid.repositories.ds3",//repository包位置
        entityManagerFactoryRef = "ds3EntityManagerFactory",
        transactionManagerRef = "ds3TransactionManager"
)
public class Ds3JPAConfig {
    @Bean(name = {"ds3TransactionManager"})
    public PlatformTransactionManager ds3TransactionManager(
            @Qualifier("ds3EntityManagerFactory") EntityManagerFactory emf){
        return new JpaTransactionManager(emf);
    }
    @Bean(name = {"ds3EntityManagerFactory"})
    public LocalContainerEntityManagerFactoryBean ds3EntityManagerFactory(
            @Qualifier(value = "ds3") DataSource dataSource,
            JpaVendorAdapter vendorAdapter) {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource);
        entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
        entityManagerFactoryBean.setPackagesToScan("cn.train.springdruid.entities.ds3");// entity包位置
        entityManagerFactoryBean.setJpaProperties(
                new Properties(){{
                    put("hibernate.hbm2ddl.auto", "update");
                    put("hibernate.show_sql", "true");
                    put("hibernate.format_sql", "true");
                }}
        );
        return entityManagerFactoryBean;
    }
}

ds1的repository包为:cn.train.springdruid.repositories.ds1,其中是OrderRepository

import cn.train.springdruid.entities.ds1.Order;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository(value = "orderRepository")
public interface OrderRepository extends JpaRepository<Order, Long> {
}

ds2的repository包为:cn.train.springdruid.repositories.ds2,其中是UserRepository

package cn.train.springdruid.repositories.ds2;

import cn.train.springdruid.entities.ds2.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository(value = "userRepository")
public interface UserRepository extends JpaRepository<User, Long> {
}

ds3的repository包为:cn.train.springdruid.repositories.ds3,其中是DetailRepository

package cn.train.springdruid.repositories.ds3;

import cn.train.springdruid.entities.ds3.Detail;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository(value = "detailRepository")
public interface DetailRepository extends JpaRepository<Detail, Long> {
}

entity

ds1的entity包为:cn.train.springdruid.entities.ds1,其中是Order

package cn.train.springdruid.entities.ds1;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "orders")
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "order_name")
    private String name;

    @Column(name = "order_price")
    private Integer price;
}

ds2的entity包为:cn.train.springdruid.entities.ds2,其中是:User

package cn.train.springdruid.entities.ds2;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "user_name")
    private String name;

    @Column(name = "user_age")
    private Integer age;
}

ds3的entity包为:cn.train.springdruid.entities.ds3,其中是:Detail

package cn.train.springdruid.entities.ds3;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "detail")
public class Detail {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;
    
    @Column(name = "description")
    private String description;
}

由此,就是整个多数据源配置与管理的全部核心代码

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 浅析Java如何优雅的设计接口状态码和异常

    浅析Java如何优雅的设计接口状态码和异常

    HTTP协议里定义了一系列的状态码用来表明请求的状态,如常用的200表示请求正常,404表示请求的资源不存在,所以本文就来和大家讨论一下如何优雅的设计接口状态码和异常,感兴趣的可以了解下
    2024-03-03
  • Java中HashMap和Hashtable的区别小结

    Java中HashMap和Hashtable的区别小结

    本文主要介绍了Java中HashMap和Hashtable的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 简单了解Java程序运行整体流程

    简单了解Java程序运行整体流程

    这篇文章主要介绍了简单了解Java程序运行整体流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • 利用Log4j将不同Package的日志输出到不同文件的方法

    利用Log4j将不同Package的日志输出到不同文件的方法

    日志是应用软件中不可缺少的部分,Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录。这篇文章主要介绍了利用Log4j将不同Package的日志输出到不同文件的方法,需要的朋友可以参考借鉴,下面来跟着小编一起学习学习吧。
    2017-01-01
  • Java深入探索线程安全和线程通信的特性

    Java深入探索线程安全和线程通信的特性

    这篇文章主要介绍了Java线程安全和线程通信的特性,线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况
    2022-05-05
  • SpringBoot 项目中的图片处理策略之本地存储与路径映射

    SpringBoot 项目中的图片处理策略之本地存储与路径映射

    在SpringBoot项目中,静态资源存放在static目录下,使得前端可以通过URL来访问这些资源,我们就需要将文件系统的文件路径与URL建立一个映射关系,把文件系统中的文件当成我们的静态资源即可,本文给大家介绍SpringBoot本地存储与路径映射的相关知识,感兴趣的朋友一起看看吧
    2023-12-12
  • java获取系统路径字体、得到某个目录下的所有文件名、获取当前路径

    java获取系统路径字体、得到某个目录下的所有文件名、获取当前路径

    这篇文章主要介绍了java获取系统路径字体、得到某个目录下的所有文件名、获取当前路径,需要的朋友可以参考下
    2014-04-04
  • 基于Java代码实现游戏服务器生成全局唯一ID的方法汇总

    基于Java代码实现游戏服务器生成全局唯一ID的方法汇总

    我们在做服务器系统开发的时候,为了适应数据大并发的请求,需要插入数据库之前生成一个全局的唯一id,纠结全局唯一id怎么生成呢?下面小编给大家分享Java代码实现游戏服务器生成全局唯一ID的方法汇总,涉及到优劣势方面的知识点,对此感兴趣的朋友一起看看吧
    2016-10-10
  • JavaEE实现前后台交互的文件上传与下载

    JavaEE实现前后台交互的文件上传与下载

    这篇文章主要介绍了JavaEE实现前后台交互的文件上传与下载,分享相关技术,实现文件上传下载功能,需要的朋友可以参考下
    2015-11-11
  • java UDP实现一个聊天工具的示例代码

    java UDP实现一个聊天工具的示例代码

    这篇文章主要介绍了java UDP实现一个聊天工具的示例代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01

最新评论