SpringBoot整合Jpa实现多数据源

SpringBoot整合Jpa实现多数据源

前言: 最近工作中需要用到两个数据源,刚好是SpringBoot项目整合的JPA,之前有写过SpringBoo Mybatis Druid配置多数据源 的文章,不过这次是 SpringBoot JPA Hikari 配置多数据源。好了,废话不多说,直接进入正题。

首先,我这里的SpringBoot版本是2.3.1.RELEASE,这个很重要,如果你的版本是低于2.1.x的,可能会有些依赖不一样,导致程序报红色异常(找不到方法或者类)。

一 首先,配置文件application.yml

spring:

  datasource:
    type: com.zaxxer.hikari.HikariDataSource #指定hikari数据源
    
    #主数据库源连接信息
    master:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql://localhost:3306/datasourceone?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&useSSL=false
      username: root
      password: root

    #从数据源连接信息
    slaver:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql://localhost:3306/datasourcetwo?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&useSSL=false
      username: root
      password: root

  jpa:
    show-sql: true  #显示sql语句,线上false关掉
    hibernate:
      ddl-auto: update  #每次启动项目更新表结构

二 然后,多数据源配置类

简单说明:主从数据源配置几乎一样,区别详见代码注释

2.1主数据源配置类
避免找错类,我把类的全路径全部贴出来

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
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.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
import java.util.Objects;


/**
 * 主数据源配置,和从(其他)数据源的区别在于多了个@Primary注解,意思是主要的,多数据源必须设置一个主数据源
 * 其他说明请看注释...
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactoryMaster",//配置连接工厂 entityManagerFactory
        transactionManagerRef = "transactionManagerMaster", //配置事物管理器  transactionManager
        basePackages = {"com.study.jpa.dao.master"} //配置主dao(repository)所在目录
)
public class MasterDataSourceConfig {

    @Autowired
    @Qualifier("masterDataSource")  //指定这是主数据源,为了和从(其他)数据源区别开,因为@Autowired不能导入名称相同的是bean
    private DataSource dataSourceMaster;
    @Autowired
    private JpaProperties jpaProperties;
    @Autowired
    private HibernateProperties hibernateProperties;


    /**
     * 多了个@Primary
     */
    @Primary
    @Bean("entityManagerMaster")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return Objects.requireNonNull(entityManagerFactoryBean(builder).getObject()).createEntityManager();
    }

    /**
     * 多了个@Primary
     */
    @Primary
    @Bean("entityManagerFactoryMaster")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(dataSourceMaster)
                .properties(getVendorProperties())
                //设置实体类所在目录
                .packages("com.study.jpa.model.master")
                //持久化单元名称,当存在多个EntityManagerFactory时,需要制定此名称
                .persistenceUnit("masterPersistenceUnit")
                .build();

    }

    private Map<String, Object> getVendorProperties() {
        return hibernateProperties.determineHibernateProperties(
                jpaProperties.getProperties(),
                new HibernateSettings()
        );
    }

    /**
     * 多了个@Primary
     */
    @Primary
    @Bean("transactionManagerMaster")
    public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(Objects.requireNonNull(entityManagerFactoryBean(builder).getObject()));
    }

}

2.2从数据源配置类

/**
 * 从数据源配置,和主数据源的配置几乎一样,区别在于没有@Primary注解
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactorySlave",//注意名称和主数据源不一样
        transactionManagerRef = "transactionManagerSlave",//注意名称和主数据源不一样
        basePackages = {"com.study.jpa.dao.slaver"}//配置从dao(repository)所在目录
)
public class SlaveDataSourceConfig {

    @Autowired
    @Qualifier("slaverDataSource") //注意指定从数据源
    private DataSource dataSource;
    @Autowired
    private JpaProperties jpaProperties;
    @Autowired
    private HibernateProperties hibernateProperties;


    @Bean("entityManagerSlave")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return Objects.requireNonNull(localContainerEntityManagerFactoryBean(builder).getObject()).createEntityManager();
    }

    @Bean("entityManagerFactorySlave")
    public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(dataSource)
                .properties(getVendorProperties())
                //设置实体类所在目录
                .packages("com.study.jpa.model.slaver")
                //持久化单元名称,当存在多个EntityManagerFactory时,需要制定此名称
                .persistenceUnit("slavePersistenceUnit")
                .build();
    }

    private Map<String, Object> getVendorProperties() {
        return hibernateProperties.determineHibernateProperties(
                jpaProperties.getProperties(),
                new HibernateSettings()
        );
    }

    @Bean("transactionManagerSlave")
    public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(Objects.requireNonNull(localContainerEntityManagerFactoryBean(builder).getObject()));
    }

}

2.3数据源配置类

/**
 * 数据源配置类
 */
@Configuration
public class DataSourceConfig {

    /**
     * 创建名为 masterDataSource 的数据源
     */
    @Primary
    @Bean(name = "masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }


    /**
     * 创建名为 slaverDataSource 的数据源
     */
    @Bean(name = "slaverDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.slaver")
    public DataSource slaverDataSource() {
        return DataSourceBuilder.create().build();
    }

}

二 接着,项目包结构以及测试类
SpringBoot整合Jpa实现多数据源_第1张图片

注意:因为有两个USerDao,所以需要分别指定名称,避免@Autowired导入异常,指定了名称之后,其实@Qualifier(“masterUserDao”)注解是可以去掉的。

最后分别在datasourceone数据库和datasourcetwo数据库插入一条数据,测试结果OK:
SpringBoot整合Jpa实现多数据源_第2张图片
SpringBoot整合Jpa实现多数据源_第3张图片
OK,到此SprigBoot整合JPA配置多数据源测试完毕,希望能够帮到有需要的朋友~

你可能感兴趣的:(随笔,java,mysql)