[spring][spring-boot] Spring boot์์ multi-datasource ํ์ฉํ๊ธฐ
Spring boot์์ multi-datasource ํ์ฉํ๊ธฐ.
๋ชฉ์
๋๋ถ๋ถ์ ๊ฒฝ์ฐ 1๊ฐ์ datasource๋ฅผ ์ฌ์ฉํ์ง๋ง ์๋น์ค๊ฐ ์ปค์ง๊ณ ์๊ตฌ์ฌํญ์ ๋ฐ๋ผ ๋ค๋ฅธ datasource์ ์ ๊ทผํด์ผ ํ ์ ์๋ค.
์ด๋ฅผ ๋๋นํ์ฌ multi-datasource ์ ์ ํ ์คํธ๋ฅผ ์งํํ๋ค.
์ ํ ์์ (@see MainRepositoryConfig.java, OtherRepositoryConfig.java, DataSourceProperties.java)
JPA๋ EntityManagerFactory ๋ก๋ถํฐ EntityManager์ TransactionManager๋ฅผ ์์ฑํ์ฌ ์ฌ์ฉํด์ผ ํ๋ค.
default EntityManager* ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ @Transactional ์ ์ค์ ํ ๋ ๋ง๋ค transactionManager name์ ์ง์ ํด์ค๋ค.
๊ณผ์
DataSourceProperties.java์์ DataSourceBuilder๋ฅผ ์ด์ฉํ์ฌ ๊ฐ๊ฐ์ properties๋ฅผ ์กฐํ, Datasource๋ฅผ ์์ฑํ๋ค.
MainRepositoryConfig.java, OtherRepositoryConfig.java ์์ EntityManagerFactory๋ฅผ ์์ฑํ๋ค.
๊ฐ๊ฐ์ ๋ง๋ Datasource ๋ฅผ injection ํ๊ณ , entity class๊ฐ ํฌํจ๋์ด ์๋ package๋ฅผ ์ง์ ํ๋ค.
์์์ ์์ฑํ EntityManagerFactory๋ฅผ ๊ธฐ๋ฐ์ผ๋ก EntityManger, TransactionManager๋ฅผ ์์ฑํ๋ค.
์ฃผ์) default EntityMangaerFactory ๋ฑ์ด ์์ฑ๋์ง ์์ผ๋ฏ๋ก @Primary ๋ฅผ ์ด์ฉํ์ฌ ์ฐ์ ์์๋ฅผ ์ค์ ํด๋๋ค.
ํด๋น ์ค์ ์ด ๋ค์ด์๋ class ์ต ์๋จ์ ์๋์ ๊ฐ์ annotation์ ์์ฑํ๋ค.
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(); } }
MainRepositoryConfig.java
์ฃผ์) transactionManger ์ entityManager, entityManagerFactory์ ๋ช ์์ ์ผ๋ก bean name ์ ์ง์ ํ์ง ์์ ๊ฒฝ์ฐ injection error๊ฐ ๋ฐ์ํ ์ ์์ผ๋ฏ๋ก ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด @Primary annotation์ ๋ถ์ฌ์ค๋ค.
entityManagerFactory๋ฅผ ์์ฑํ ๋ package๋ฅผ ์ง์ ํด์ฃผ๊ฒ ๋์ด ์๋๋ฐ, ์ด ๊ณณ์ Entity ๋ก ์ฌ์ฉํ๋ java class๊ฐ ํฌํจ๋์ด ์์ด์ผ ํ๋ค. ์ ๊ทธ๋ฌ๋ฉด ์๋ฌ๋จ.
@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()); } }
OtherRepositoryConfig.java
๋ค๋ฅธ Database์ ์ ๊ทผํ๋ ค๋ ๊ฒฝ์ฐ.
@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: # db 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
ํ ์คํธ
์ ํ์ฌํญ
datasource์ ๋ง๋ database๋ฅผ ์ค์ ํ๋ค.
Application.java๋ฅผ ์คํํ๋ค.
์คํ ํ MainRepositoryConfig๋ก ์ค์ ๋ ๊ณณ์ accountํ ์ด๋ธ์ด, OtherRepositoryConfig๋ก ์์ฑ๋ ๊ณณ์ youtube_movie ํ ์ด๋ธ์ด ์์ฑ๋๊ณ ๋ฐ์ดํฐ๊ฐ ๋ค์ด์ค๋์ง ํ์ธํ๋ค.














