IT Blog

home

How to use multi-datasource in Spring boot project

09 Jan 2016

Spring boot에서 multi-datasource 활용하기.

ex. MainRepositoryConfig.java @Configuration @EnableTransactionManagement @EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryMain", transactionManagerRef = "transactionManagerMain", basePackages = { "com.sk.prototype.repository.main" }

* 주의
	entity 이름을 명시적으로 지정해주지 않으면 default entityManager가 생성되는데, 이 상황에서는 굳이 쓸 필요가 없다.

DatasourceProperties.java

 @Configuration
 @EnableConfigurationProperties
 public class DataSourceProperties {
 
     @Bean(name = "mainDataSource") @Qualifier("mainDataSource")
     @Primary
     @ConfigurationProperties(prefix="spring.datasource.main")
     public DataSource mainDataSource() {
         return DataSourceBuilder.create().build();
     }
 
     @Bean(name = "otherDataSource") @Qualifier("otherDataSource")
     @ConfigurationProperties(prefix="spring.datasource.other")
     public DataSource otherDataSource() {
         return DataSourceBuilder.create().build();
     }
 }
* 주의) transactionManger 와 entityManager, entityManagerFactory에 명시적으로 bean name 을 지정하지 않은 경우 injection error가 발생할 수 있으므로 이를 방지하기 위해 @Primary annotation을 붙여준다.
* entityManagerFactory를 생성할 때 package를 지정해주게 되어 있는데, 이 곳에 Entity 로 사용하는 java class가 포함되어 있어야 한다. 안 그러면 에러남.

MainRepositoryConfig.java

 @Configuration
 @EnableTransactionManagement
 @EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryMain", transactionManagerRef = "transactionManagerMain",
                       basePackages = { "com.sk.prototype.repository.main" } )
 public class MainRepositoryConfig {
   @Inject
   private JpaProperties jpaProperties;
 
   @Inject @Qualifier("mainDataSource")
   private DataSource mainDataSource;
 
   @Bean(name = "entityManagerMain")
   @Primary
   public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
       return entityManagerFactoryMain(builder).getObject().createEntityManager();
   }
 
   @Bean(name = "entityManagerFactoryMain")
   @Primary
   public LocalContainerEntityManagerFactoryBean entityManagerFactoryMain (EntityManagerFactoryBuilder builder) {
       return builder
               .dataSource(mainDataSource)
               .properties(getVendorProperties(mainDataSource))
               .packages("com.sk.prototype.domain.main")
               .persistenceUnit("mainPersistenceUnit")
               .build();
   }
 
   private Map<String, String> getVendorProperties(DataSource dataSource) {
       return jpaProperties.getHibernateProperties(dataSource);
   }
 
   @Bean(name = "transactionManagerMain")
   @Primary
   PlatformTransactionManager transactionManagerMain(EntityManagerFactoryBuilder builder) {
       return new JpaTransactionManager(entityManagerFactoryMain(builder).getObject());
   }
 }
* 다른 Database에 접근하려는 경우. OtherRepositoryConfig.java ```    @Configuration    @EnableTransactionManagement    @EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryOther", transactionManagerRef = "transactionManagerOther",
                      basePackages = { "com.sk.prototype.repository.other" } )    public class OtherRepositoryConfig {
   @Inject
   private JpaVendorAdapter jpaVendorAdapter;
 
   @Inject
   private JpaProperties jpaProperties;
 
   @Inject @Qualifier("otherDataSource")
   private DataSource otherDataSource;
 
   @Bean(name = "entityManagerOther")
   public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
       return entityManagerFactoryOther(builder).getObject().createEntityManager();
   }
 
   @Bean(name = "entityManagerFactoryOther")
   public LocalContainerEntityManagerFactoryBean entityManagerFactoryOther (EntityManagerFactoryBuilder builder) {
       return builder
               .dataSource(otherDataSource)
               .properties(getVendorProperties(otherDataSource))
               .packages("com.sk.prototype.domain.other")
               .persistenceUnit("otherPersistenceUnit")
               .build();
   }
 
   private Map<String, String> getVendorProperties(DataSource dataSource) {
       return jpaProperties.getHibernateProperties(dataSource);
   }
 
   @Bean(name = "transactionManagerOther")
   PlatformTransactionManager transactionManagerOther(EntityManagerFactoryBuilder builder) {
       return new JpaTransactionManager(entityManagerFactoryOther(builder).getObject());
   }    } ```

application.yml spring: datasource: main: platform: mysql url: jdbc:mysql://localhost/main-db username: root password: driverClassName: com.mysql.jdbc.Driver other: platform: mysql url: jdbc:mysql://localhost/other-db username: root password: driverClassName: com.mysql.jdbc.Driver