[SPRING] Mybatis 봄 여러 데이터베이스 Java 구성
SPRINGMybatis 봄 여러 데이터베이스 Java 구성
Spring과 Mybatis로 작업하고 있는데 두 개의 데이터베이스가 있습니다. 첫 번째 데이터베이스의 구성은 상대적으로 쉽지만 Spring과 트랜잭션을 사용하여 두 번째 데이터베이스를 처리 할 수는 없습니다. 여기에 제 코드가 있습니다.
@Configuration
@ComponentScan(basePackages = {"hernandez.service", "hernandez.dao"})
@EnableTransactionManagement
@MapperScan(basePackages="hernandez.mapper" )
@Import(DbConfig2.class)
public class AppConfig {
@Bean(name = "dataSource")
public DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource("com.mysql.jdbc.Driver",
"jdbc:mysql://localhost:3306/northwind", "root", "");
return ds;
}
@Bean
public SqlSessionFactoryBean sqlSessionFactory() {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource());
return factoryBean;
}
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}
@Configuration
@MapperScan("loli.mapper" )
public class DbConfig2 {
@Bean(name = "dataSource_2")
public DataSource dataSource2() {
DriverManagerDataSource ds = new DriverManagerDataSource("com.mysql.jdbc.Driver",
"jdbc:mysql://localhost:3306/dmsolut_dmsms", "root", "");
return ds;
}
@Bean
public SqlSessionFactory sqlSessionFactory2() throws Exception{
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource2());
return factoryBean.getObject();
}
@Bean(name = "transactionManager_2")
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource2());
}
}
순수 Spring Java 구성으로 작업하거나 적어도 XML로 작업 할 수있는 방법이 있습니까? Mybatis-Spring 프로젝트에서 두 개의 데이터베이스가 작동하도록하는 공식 문서는 없습니다.
해결법
-
==============================
1.mybatis가있는 다중 데이터 소스가 현재 내 프로젝트에서 사용됩니다. 이 예제는 application.xml에 추가합니다.
mybatis가있는 다중 데이터 소스가 현재 내 프로젝트에서 사용됩니다. 이 예제는 application.xml에 추가합니다.
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/> <property name="url" value="${center.connectionURL}"/> <property name="username" value="${userName}"/> <property name="password" value="${password}"/> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.xxx.dao.center"/> <property name="sqlSessionFactoryBeanName" value="cneterSqlSessionFactory"/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" name="cneterSqlSessionFactory"> <property name="dataSource" ref="dataSource"></property> <property name="mapperLocations" value="classpath*:mapperConfig/center/*.xml"/> <property name="configLocation" value="classpath:mybatis-config.xml"/> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> <!--center db end--> <!--exdb--> <bean id="dataSourceEx" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/> <property name="url" value="${ex.connectionURL}"/> <property name="username" value="${userName}"/> <property name="password" value="${password}"/> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.xxx.dao.ex"/> <property name="sqlSessionFactoryBeanName" value="exSqlSessionFactory"/> </bean> <bean id="sqlSessionFactoryEx" class="org.mybatis.spring.SqlSessionFactoryBean" name="exSqlSessionFactory"> <property name="dataSource" ref="dataSourceEx"></property> <property name="mapperLocations" value="classpath*:mapperConfig/ex/*.xml"/> <property name="configLocation" value="classpath:mybatis-config.xml"/> </bean> <bean id="transactionManagerEx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSourceEx"/> </bean>
-
==============================
2.프로젝트에서 사용하는 java config 예제를 사용하여 답변 추가 :
프로젝트에서 사용하는 java config 예제를 사용하여 답변 추가 :
import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.type.JdbcType; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; @Configuration @ComponentScan(basePackages = "com.mycompany") @EnableTransactionManagement(proxyTargetClass = true) public class ApplicationConfig2 { public static final String DATA_SOURCE_NAME_1 = "jdbc/dataSource1"; public static final String DATA_SOURCE_NAME_2 = "jdbc/dataSource2"; public static final String SQL_SESSION_FACTORY_NAME_1 = "sqlSessionFactory1"; public static final String SQL_SESSION_FACTORY_NAME_2 = "sqlSessionFactory2"; public static final String MAPPERS_PACKAGE_NAME_1 = "com.mycompany.mappers.dao1"; public static final String MAPPERS_PACKAGE_NAME_2 = "com.mycompany.mappers.dao2"; @Bean public DataSource dataSource1() { JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); return dsLookup.getDataSource(DATA_SOURCE_NAME_1); } @Bean public DataSource dataSource2() { JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); return dsLookup.getDataSource(DATA_SOURCE_NAME_2); } @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } @Bean(name = SQL_SESSION_FACTORY_NAME_1) public SqlSessionFactory sqlSessionFactory1(DataSource dataSource1) throws Exception { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setTypeHandlersPackage(DateTimeTypeHandler.class.getPackage().getName()); sqlSessionFactoryBean.setDataSource(dataSource1); SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject(); sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true); sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL); return sqlSessionFactory; } @Bean(name = SQL_SESSION_FACTORY_NAME_2) public SqlSessionFactory sqlSessionFactory2(DataSource dataSource2) throws Exception { SqlSessionFactoryBean diSqlSessionFactoryBean = new SqlSessionFactoryBean(); diSqlSessionFactoryBean.setTypeHandlersPackage(DateTimeTypeHandler.class.getPackage().getName()); diSqlSessionFactoryBean.setDataSource(dataSource2); SqlSessionFactory sqlSessionFactory = diSqlSessionFactoryBean.getObject(); sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true); sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL); return sqlSessionFactory; } @Bean public MapperScannerConfigurer mapperScannerConfigurer1() { MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setBasePackage(MAPPERS_PACKAGE_NAME_1); configurer.setSqlSessionFactoryBeanName(SQL_SESSION_FACTORY_NAME_1); return configurer; } @Bean public MapperScannerConfigurer mapperScannerConfigurer2() { MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setBasePackage(MAPPERS_PACKAGE_NAME_2); configurer.setSqlSessionFactoryBeanName(SQL_SESSION_FACTORY_NAME_2); return configurer; } }
-
==============================
3.내 경험에 비추어 볼 때, DataSource Bean 중 하나에 @Primary도 추가해야한다. 그렇지 않은 경우, NoUniqueBeanDefinitionException가 throw됩니다.
내 경험에 비추어 볼 때, DataSource Bean 중 하나에 @Primary도 추가해야한다. 그렇지 않은 경우, NoUniqueBeanDefinitionException가 throw됩니다.
@Bean @Primary public DataSource dataSource1() { JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); return dsLookup.getDataSource(DATA_SOURCE_NAME_1); } @Bean public DataSource dataSource2() { JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); return dsLookup.getDataSource(DATA_SOURCE_NAME_2); }
-
==============================
4.스프링의 AbstractRoutingDataSource를 확장하고 decideCurrentLookupKey () 메서드를 재정 의하여 사용할 수 있습니다.
스프링의 AbstractRoutingDataSource를 확장하고 decideCurrentLookupKey () 메서드를 재정 의하여 사용할 수 있습니다.
스프링 구성
스프링 구성에서 별도의 데이터 소스를 정의 할 수 있습니다.
<!-- db2 data source --> <bean id="db2DataSource" class="com.ibm.db2.jdbc.app.DB2Driver"> <property name="serverName" value="${db2.jdbc.serverName}" /> <property name="portNumber" value="${db2.jdbc.portNumber}" /> <property name="user" value="${db2.jdbc.username}" /> <property name="password" value="${db2.jdbc.password}" /> <property name="databaseName" value="${db2.jdbc.databaseName}" /> </bean> <!-- mysql data source --> <bean id="mysqlDataSource" class="com.mysql.jdbc.Driver"> <property name="serverName" value="${mysql.jdbc.serverName}" /> <property name="portNumber" value="${mysql.jdbc.portNumber}" /> <property name="user" value="${mysql.jdbc.username}" /> <property name="password" value="${mysql.jdbc.password}" /> <property name="databaseName" value="${mysql.jdbc.databaseName}" /> </bean>
데이터 소스를 고객과 연결 :
<bean id="customer" class="com.example.Customer"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="dataSource" class="com.example.datasource.CustomerRoutingDataSource"> <property name="targetDataSources"> <map key-type="com.example.Customer"> <entry key="db2" value-ref="mysqlDataSource"/> <entry key="mysql" value-ref="db2DataSource"/> </map> </property> <property name="defaultTargetDataSource" ref="mysql"/> </bean>
자바
package com.example; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class CustomerRoutingDataSource extends AbstractRoutingDataSource { @Bean CustomerContextHolder context; @Override protected Object determineCurrentLookupKey() { return context.getCustomerType(); } }
기본적으로 각 요청에는 해당 컨텍스트가 있습니다. 매핑 된 키를 사용하여 요청과 데이터 소스를 연결할 수 있습니다. 자세한 내용은 여기에서 확인할 수 있습니다. dynamic-datasource-routing
-
==============================
5.
<bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource1" /> <property name="configLocation"> <value>classpath:com/dtcc/dao/impl/DaoSqlMapConfig_MyBatis1.xml</value> </property> <property name="transactionFactory"> <bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" /> </property> <property name="mapperLocations" value="classpath*:com/dtcc/dao/impl/DaoEmfMyBatis.sp.xml"/> </bean> <bean id="sqlSession1" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory1" /> </bean> <!-- MyBatis Changes Ends --> <bean id="daoEmf" class="com.dtcc.dao.DaoEmfImpl"> <property name="connectionType"><ref local="com.dtcc.sharedservices.utils.resources.ConnTypes.IBM_DB2_CONNECTION" /></property> <property name="jndiNameForLogging"><ref local="dataSourceName1" /></property> <property name="sqlSessionTemplate"> <ref local="sqlSession1" /></property> <property name="applicationLog"><ref local="appLog" /></property> </bean>
앞서 언급했듯이 DaoImpl에 상응하는 sessionFactory를 제공해야합니다. 둘 이상의 sessionFactory가있는 경우 DaoImpl 클래스에서 SqlSessionTemplate을 자동으로 호출 할 수 없습니다. 각 세션 팩토리에 대해 고유 한 이름을 지정하고 해당 DaoImpl 클래스에 매핑하십시오. DaoImpl 클래스에서 Setter 메소드를 사용하여 SqlSessionTemplate에 대한 객체를 생성하면 아래와 같이 sqlSessionTemplate 객체를 사용하여 db 호출을 할 수 있습니다. this.sqlSessionTemplate.selectList ( "ProcedureID", 매개 변수);
from https://stackoverflow.com/questions/18201075/mybatis-spring-multiple-databases-java-configuration by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 확인란 값이 false 일 때 객체에 바인딩되지 않습니까? (0) | 2019.02.01 |
---|---|
[SPRING] Spring jUnit 테스트 등록 정보 파일 (0) | 2019.02.01 |
[SPRING] 스프링 구성 (0) | 2019.02.01 |
[SPRING] 프록시가 작동하지 않는 CGLIB 서비스의 자산 조롱 (0) | 2019.02.01 |
[SPRING] Hibernate에 의해로드 된 엔티티로 Spring을 통해 필드 주입 (0) | 2019.02.01 |