SpringBoot和JPA多数据源整合

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: SpringBoot和JPA多数据源整合

前言

项目中经常会遇到使用多个数据源的情况。这里是基于 JPA 来配置多个数据源。此配置是给予java1.8,闲话少说,一起来看看文章内容吧。

1.引入maven依赖


<dependencies>
    <!--****spring data jpa ****-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!--**** web-services ****-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web-services</artifactId>
    </dependency>

    <!--**** lombok ****-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <!--**** 阿里的数据源 ****-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.10</version>
    </dependency>

    <!--**** mysql ****-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>

    <!--**** test ****-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

2.配置数据库和jpa一些简易配置


spring:
  datasource:
    primary:
      driver-class-name: com.mysql.jdbc.Driver      url: jdbc:mysql://localhost:3306/primary?useUnicode=true&characterEncoding=UTF-8&useOldAliasMetadataBehavior=true&serverTimezone=Asia/Shanghai
      username: root
      password: root
    second:
      driver-class-name: com.mysql.jdbc.Driver      url: jdbc:mysql://localhost:3306/second?useUnicode=true&characterEncoding=UTF-8&useOldAliasMetadataBehavior=true&serverTimezone=Asia/Shanghai
      username: root
      password: root
  jpa:
    show-sql: false
    hibernate:
      format_sql: true
      primary-dialect: org.hibernate.dialect.MySQL55Dialect
      second-dialect: org.hibernate.dialect.MySQL55Dialect

3.多数据源配置

DataSourceConfig

@Configuration
public class DataSourceConfig {

    /**
     * 第一个数据连接,默认优先级最高
     * @return
     */
    @Primary
    @Bean(name = "primaryDataSource")
    @Qualifier("primaryDataSource")
    @ConfigurationProperties(prefix="spring.datasource.primary")
    public DataSource PrimaryDataSource() {
        return DataSourceBuilder.create().type(DruidDataSource.class).build();
    }

    /**
     * 第二个数据源
     * @return
     */
    @Bean(name = "secondDataSource")
    @Qualifier("secondDataSource")
    @ConfigurationProperties(prefix="spring.datasource.second")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().type(DruidDataSource.class).build();
    }
}

PrimaryConfig

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef="entityManagerFactoryPrimary",
        transactionManagerRef="transactionManagerPrimary",
        basePackages= { "xin.zhuyao.springbootjapdatasource.repository.primary" })
public class PrimaryConfig {

    @Autowired
    private Environment env;

    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;

    @Primary
    @Bean(name = "entityManagerPrimary")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
    }

    @Primary
    @Bean(name = "entityManagerFactoryPrimary")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(primaryDataSource)
                .properties(getVendorProperties())
                .packages("xin.zhuyao.springbootjapdatasource.domain.primary")
                .persistenceUnit("primaryPersistenceUnit")
                .build();
    }



    private Map<String, String> getVendorProperties() {
        Map<String, String> jpaProperties = new HashMap<>(16);
        jpaProperties.put("hibernate.hbm2ddl.auto", "update");
        jpaProperties.put("hibernate.show_sql", env.getProperty("spring.jpa.show-sql"));
        jpaProperties.put("hibernate.format_sql", env.getProperty("spring.jpa.hibernate.format_sql"));
        jpaProperties.put("hibernate.dialect", env.getProperty("spring.jpa.hibernate.primary-dialect"));
        jpaProperties.put("hibernate.current_session_context_class", "org.springframework.orm.hibernate5.SpringSessionContext");
        return jpaProperties;
    }

    @Primary
    @Bean(name = "transactionManagerPrimary")
    public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
    }
}

SecondConfig

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        //实体管理
        entityManagerFactoryRef="entityManagerFactorySecond",
        //事务管理
        transactionManagerRef="transactionManagerSecond",
        //实体扫描,设置Repository所在位置
        basePackages= { "xin.zhuyao.springbootjapdatasource.repository.second" })
public class SecondConfig {

    @Autowired
    @Qualifier("secondDataSource")
    private DataSource secondDataSource;

    @Autowired
    private Environment env;

    @Bean(name = "entityManagerSecond")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactorySecond(builder).getObject().createEntityManager();
    }

    @Bean(name = "entityManagerFactorySecond")
    public LocalContainerEntityManagerFactoryBean entityManagerFactorySecond (EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(secondDataSource)
                .properties(getVendorProperties())
                .packages("xin.zhuyao.springbootjapdatasource.domain.second")
                .persistenceUnit("secondPersistenceUnit")
                .build();
    }

    private Map<String, String> getVendorProperties() {
        Map<String, String> jpaProperties = new HashMap<>(16);
        jpaProperties.put("hibernate.hbm2ddl.auto", "update");
        jpaProperties.put("hibernate.show_sql", env.getProperty("spring.jpa.show-sql"));
        jpaProperties.put("hibernate.dialect", env.getProperty("spring.jpa.hibernate.Second-dialect"));
        jpaProperties.put("hibernate.format_sql", env.getProperty("spring.jpa.hibernate.format_sql"));
        jpaProperties.put("hibernate.current_session_context_class", "org.springframework.orm.hibernate5.SpringSessionContext");
        return jpaProperties;
    }

    @Bean(name = "transactionManagerSecond")
    PlatformTransactionManager transactionManagerSecond(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactorySecond(builder).getObject());
    }
}

640.png

这样整体就结束了,配置就结束了,可以写测试了。

4.测试

UserPrimaryEntity

@Data
@Entity
@NoArgsConstructor
@Table(name = "t_user")
@FieldDefaults(level = AccessLevel.PRIVATE)
public class UserPrimaryEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    /**
     * 名称
     */
    String name;

    /**
     * 性别
     */
    String sex;
}

UserSecondEntity

@Data
@Entity
@NoArgsConstructor
@Table(name = "t_user")
@FieldDefaults(level = AccessLevel.PRIVATE)
public class UserSecondEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    /**
     * 名称
     */
    String name;

    /**
     * 性别
     */
    String sex;
}

UserPrimaryRepository

@Repository
public interface UserPrimaryRepository extends JpaRepository<UserPrimaryEntity, Long> {

}

UserSecondRepository


@Repository
public interface UserSecondRepository extends JpaRepository<UserSecondEntity, Long> {

}

SpringbootJapDatasourceApplicationTests


@SpringBootTest
class SpringbootJapDatasourceApplicationTests {

    @Autowired
    private UserPrimaryRepository userPrimaryRepository;
    @Autowired
    private UserSecondRepository userSecondRepository;

    @Test
    void contextLoads() {
        System.out.println(userPrimaryRepository.findAll());
        System.out.println(userSecondRepository.findAll());
    }

}

测试结果:

[UserPrimaryEntity(id=1, name=zy, sex=男)]
[UserSecondEntity(id=1, name=wl, sex=女)]

源码:https://github.com/zywaiting/springboot-jap-datasource

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
10天前
|
Java 数据库连接
SpringBoot配置多数据源实战
第四届光学与机器视觉国际学术会议(ICOMV 2025) 2025 4th International Conference on Optics and Machine Vision
38 8
|
1月前
|
SQL Java 关系型数据库
Springboot引入jpa来管理数据库
Springboot引入jpa来管理数据库
35 0
Springboot引入jpa来管理数据库
|
5月前
|
druid Java 关系型数据库
Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多数据源
Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多数据源
|
1月前
|
SQL Java 数据库连接
springBoot+Jpa(hibernate)数据库基本操作
springBoot+Jpa(hibernate)数据库基本操作
42 0
|
2月前
|
Java 数据库连接 API
【Java笔记+踩坑】Spring Data JPA
从常用注解、实体类和各层编写方法入手,详细介绍JPA框架在增删改查等方面的基本用法,以及填充用户名日期、分页查询等高级用法。
【Java笔记+踩坑】Spring Data JPA
|
3月前
|
安全 Java 数据安全/隐私保护
基于SpringBoot+Spring Security+Jpa的校园图书管理系统
本文介绍了一个基于SpringBoot、Spring Security和JPA开发的校园图书管理系统,包括系统的核心控制器`LoginController`的代码实现,该控制器处理用户登录、注销、密码更新、角色管理等功能,并提供了系统初始化测试数据的方法。
58 0
基于SpringBoot+Spring Security+Jpa的校园图书管理系统
|
3月前
|
Java 关系型数据库 MySQL
|
3月前
|
Java Spring 数据库
怎样动动手指就能实现数据操作?Spring Data JPA背后的魔法揭秘
【8月更文挑战第31天】在Java开发中,数据库交互至关重要。传统的JDBC操作繁琐且难维护,而Spring Data JPA作为集成JPA的数据访问层解决方案,提供了CRUD等通用操作接口,显著减少代码量。通过继承`JpaRepository`,开发者能轻松实现数据的增删改查,甚至复杂查询和分页也不再困难。本文将通过示例详细介绍如何利用Spring Data JPA简化数据访问层的开发,提升代码质量和可维护性。
43 0
|
3月前
|
存储 Java 数据库
|
3月前
|
存储 Java API