1. 程式人生 > >spring boot jpa 多數據源配置

spring boot jpa 多數據源配置

drive hiberna hashmap pac initial config ini enable 2個

在實際項目中往往會使用2個數據源,這個時候就需要做額外的配置了。下面的配置在2.0.1.RELEASE 測試通過

1、配置文件

  配置兩個數據源

spring.datasource.url=jdbc:mysql://localhost:13306/first?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.seconddatasource.url=jdbc:mysql://localhost:3306/second?useUnicode\=true&characterEncoding=utf-8&useSSL=false
spring.seconddatasource.driverClassName=com.mysql.jdbc.Driver spring.seconddatasource.username=root spring.seconddatasource.password=

  

2、entity

  創建兩個簡單的entity,它們分別對應不同的數據庫。

  先看第一個entity,user

package com.example.first.entity;
 
@Entity
public class User {
 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private String email;
    private int age;
}

  第二個entity, product

package com.example.second.entity;
 
@Entity
public class Product {
 
    @Id
    private Long id;
    private String name;
    private double price;
}

  註意:這兩個enty位於不同的包裏面。

3、Repository

  創建兩個對應的Repository,註意他們也位於不同的包裏

  

package com.example.first.dao;
 
public interface UserRepository
  extends JpaRepository<User, Long> { }

  

package com.example.second.dao;
 
public interface ProductRepository
  extends JpaRepository<Product, Long> { }

  

4、java 配置

  有兩個數據源,需要兩個配置文件,分別配置下面這幾個Bean

  DataSource

  EntityManagerFactory

  TransactionManager

  首先配置第一個數據源,我把它作為主數據源,註意,它們都使用了@Prime註解

@Configuration
@EnableJpaRepositories(basePackages = "com.example.first.dao",
        entityManagerFactoryRef = "firstEntityManager",
        transactionManagerRef = "firstTransactionManager")
public class FirstDataSourceConfig {

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean firstEntityManager(EntityManagerFactoryBuilder builder) {

        Map<String, String> properties = new HashMap<>();
        properties.put("hibernate.implicit_naming_strategy",
                "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
        properties.put("hibernate.physical_naming_strategy",
                "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
        return builder
                .dataSource(firstDataSource())
                .packages("com.example.user.entity")
                .persistenceUnit("first")
                .properties(properties)
                .build();
    }

    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource")
    public DataSourceProperties firstDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource")
    public DataSource firstDataSource() {
        return primaryDataSourceProperties().initializeDataSourceBuilder().build();
    }


    @Primary
    @Bean(name = "firstTransactionManager")
    public PlatformTransactionManager firstTransactionManager(@Qualifier("firstEntityManager")
                                                                      EntityManagerFactory firstEntityManagerFactory) {
        return new JpaTransactionManager(firstEntityManagerFactory);
    }
}

  

  接下來配置第二個數據源,和第一個完全一致,除了沒有@Prime註解

@Configuration
@EnableJpaRepositories(
        basePackages = "com.example.second.dao",
        entityManagerFactoryRef = "secondEntityManager",
        transactionManagerRef = "secondTransactionManager"
)
public class SecondDataSourceConfig {

    @Bean
    public LocalContainerEntityManagerFactoryBean secondEntityManager(EntityManagerFactoryBuilder builder) {
        Map<String, String> properties = new HashMap<>();
        properties.put("hibernate.implicit_naming_strategy",
                "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
        properties.put("hibernate.physical_naming_strategy",
                "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
        return builder
                .dataSource(secondDataSource())
                .packages("com.example.second.entity")
                .persistenceUnit("second")
                .properties(properties)
                .build();
    }

    @Bean
    @ConfigurationProperties("spring.seconddatasource")
    public DataSourceProperties secondDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("spring.seconddatasource")
    public DataSource secondDataSource() {
        return secondDataSourceProperties().initializeDataSourceBuilder().build();
    }


    @Bean(name = "secondTransactionManager")
    public PlatformTransactionManager secondTransactionManager(@Qualifier("secondEntityManager")
                                                                      EntityManagerFactory secondEntityManagerFactory) {
        return new JpaTransactionManager(secondEntityManagerFactory);
    }
}

  

5、使用

  和單數據源的jpa使用方式基本一致。當使用事務註解是,第一個數據源的註解可以直接使用@Transactional,第二個為了區分必須使用@Transactional(value="secondTransactionManager")。可以在一個事務中調用另外一個數據源的事務。

2.0.1.RELEASE

spring boot jpa 多數據源配置