YAML
만일 다중 DB를 사용하려면. YAML설정을 바꿔줘야한다.
spring:
datasource:
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
url:
username:
password:
원래 JPA YAML설정할때 DB하나만 선택해서 사용할 때는 URL: 을 통해서 메핑을 한다면, 트랜잭션과 여러 설정들이 자동으로 이루어지게 된다. 하지만, DB가 2개일 때 부터는 아래와 같은 설정 + ConfigFile 을 작성해 주어야한다.
spring:
datasource:
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc-url:
username:
password:
second-datasource:
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc-url:
username:
password:
datasource를 각각 다른 이름을 통해서 설정해주고, 각각 맞는 DB를 설정해 주면 된다.
@Configuration
public class DataSourceConfig {
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource msSql3DataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.second-datasource")
public DataSource msSql7DataSource() {
return DataSourceBuilder.create().build();
}
}
yaml파일을 기반으로 DataSourceBuilder를 통해서 DataSource를 설정하고, 여러개의 Source중 하나에 꼭
@Primary 를 붙여줘야합니다.
@Configuration
@Profile("!test")
@EnableJpaRepositories(
basePackages = {
"com.kfr.admin.infrastructure.user",
"com.kfr.admin.infrastructure.permission",
"com.kfr.admin.infrastructure.solution",
"com.kfr.admin.infrastructure.menu",
"com.kfr.admin.infrastructure.grid",
"com.kfr.admin.infrastructure.cust",
"com.kfr.admin.infrastructure.ctrl",
"com.kfr.admin.infrastructure.auth.group",
"com.kfr.admin.presentation.refresh",
"com.kfr.admin.domain.refresh"
},// RefreshRepository 위치
entityManagerFactoryRef = "db1EntityManagerFactory",
transactionManagerRef = "db1JpaTransactionManager"
)
@MapperScan(
sqlSessionTemplateRef = "sqlSessionTemplateMsSql3"
//basePackages = {"com.kfr.admin.infrastructure.ctrl.mybatis"}
)
public class MsSql3DBConfig {
@Bean
@Primary
public EntityManagerFactory db1EntityManagerFactory(@Qualifier("msSql3DataSource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(dataSource);
factory.setPackagesToScan("com.kfr.admin.domain.user", "com.kfr.admin.domain.refresh", "com.kfr.admin.domain.permission"
, "com.kfr.admin.domain.solution", "com.kfr.admin.domain.menu", "com.kfr.admin.domain.grid", "com.kfr.admin.domain.cust",
"com.kfr.admin.domain.ctrl", "com.kfr.admin.domain.auth.group");
factory.setPersistenceUnitName("db1EntityManager");
factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
factory.afterPropertiesSet();
return factory.getObject();
}
@Bean
@Primary
public PlatformTransactionManager db1JpaTransactionManager(@Qualifier("db1EntityManagerFactory") EntityManagerFactory entityManagerFactory) {
JpaTransactionManager tm = new JpaTransactionManager();
tm.setEntityManagerFactory(entityManagerFactory);
return tm;
}
@Primary
@Bean(name = "sessionFactoryMsSql3")
public SqlSessionFactory sessionFactoryMsSql3(@Qualifier("msSql3DataSource") DataSource dataSource, ApplicationContext applicationContext) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setMapperLocations(applicationContext.getResources("classpath:/mapper/**/sql_*.xml"));
bean.setDataSource(dataSource);
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
configuration.setCallSettersOnNulls(true);
configuration.setJdbcTypeForNull(JdbcType.NULL);
bean.setConfiguration(configuration);
return bean.getObject();
}
@Primary
@Bean(name = "sqlSessionTemplateMsSql3")
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sessionFactoryMsSql3")SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
@MapperScan은 Mybatis의 @Mapper의 기능을 사용할 때 scan해주기위해서 사용하는 것이고 xml을 사용할 때는 크게 의미가없는 부분이다. 3번 DataSource의 이름을 통해서 가져온후. xml를 메핑시켜준후, sqlTemplate을 선언해줍니다.
나중에 mybatis를 사용할때 템플릿 이름으로 사용하면됩니다.
jpa도 마찬가지로 사용할 트랜잭션을 걸어주고 basePackages에다가 repository의 위치들을,
setPackagesToScan에다가 Entity를 선언해주면되고,
저렇게 Entity가 생성될때마다 추가되는 게 싫다면, DB별로 나눠서 패키지구조를 짜고, 하위를 모두 포함하게끔 하면 될 것 같다는 결론이 나왔다.
@Configuration
@MapperScan(
sqlSessionTemplateRef = "sqlSessionTemplateMsSql7"
)
public class MsSql7DBConfig {
@Bean(name = "sessionFactoryMsSql7")
public SqlSessionFactory sessionFactoryMsSql7(@Qualifier("msSql7DataSource") DataSource dataSource, ApplicationContext applicationContext) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setMapperLocations(applicationContext.getResources("classpath:/mapper/**/sql_*.xml"));
bean.setDataSource(dataSource);
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
configuration.setCallSettersOnNulls(true);
configuration.setJdbcTypeForNull(JdbcType.NULL);
bean.setConfiguration(configuration);
return bean.getObject();
}
@Primary
@Bean(name = "sqlSessionTemplateMsSql7")
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sessionFactoryMsSql7")SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
아래도 동일하게 7번 DataSource의 이름을 통해서 가져온후. xml를 메핑시켜준후, sqlTemplate을 선언해줍니다.
이렇게 되면 두개의 DB를 동시에 사용할 수 있고, JPA Mybatis 둘다 사용할 수 있습니다.
'Trouble Shooting' 카테고리의 다른 글
태태개발일지 - GPT 파인 튜닝 (0) | 2025.06.23 |
---|---|
태태개발일지 - JPA N+1 (1) | 2024.10.25 |