Child pages
  • 스프링과 마이바티스 에서 다중 데이타소스 사용하기

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

 Spring 과 MyBatis (iBatis) 를 개발 환경으로 사용할 경우 여러 개의 datasource 를 써야 되는 경우가 있다.

 


여러 개의 data source 에 연결해야 할 경우 Mybatis config와 mapper 를 별도의 패키지로 분리하는게 개인적으로는 관리가 용이하다.

 


application context xml

Note

단위 테스트 및 stand-alone 용이라 Data Source 설정이 WAS에 있지 않고 spring context 에 있고 BoneCP 나 c3p0 같은 Connection Pool 을 사용하지 않고 스프링의  SimpleDriverDataSource 로 설정되어 있다.

Code Block
languagexml
titledatabase-context.xml
linenumberstrue
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
				http://www.springframework.org/schema/beans/spring-beans.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
				http://www.springframework.org/schema/tx 
				http://www.springframework.org/schema/tx/spring-tx.xsd 
				http://www.springframework.org/schema/jee
				http://www.springframework.org/schema/jee/spring-jee.xsd">

	<!-- multiple data source & sqlSessionFactory -->
	<bean id="ds-one" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
		<property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
		<property name="url" value="jdbc:oracle:thin:@//db1.example.com:1521/ocrl" />
		<property name="username" value="user" />
		<property name="password" value="userpwd" />
	</bean>
	<bean id="ds-two" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
		<property name="driverClass" value="com.mysql.jdbc.Driver" />       
        <property name="url" value="jdbc:mysql://db2.example.com:3306/lesstif?useUnicode=true&amp;characterEncoding=utf8" />
        <property name="username" value="userid" />
        <property name="password" value="useriduserPwd" />
	</bean>

	<bean id="dsOneSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
		p:mapperLocations="classpath:/com/example/mapper-one/*mapper.xml"
		p:configLocation="classpath:/com/example/dsone-mybatis-config.xml" 
		p:dataSource-ref="ds-one" />

	<bean id="dsTwoSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
		p:mapperLocations="classpath:/com/example/mapper-two/*mapper.xml"
		p:configLocation="classpath:/com/example/dstwo-mybatis-config.xml" 
		p:dataSource-ref="ds-two" />
  	
	<bean id="dsOneScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"
		p:basePackage="com.example.mapper-one" />
 
	<bean id="dsTwoScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"
		p:basePackage="com.example.mapper-two" />

	<bean id="dsOnetransactionManager"	class="org.springframework.jdbc.datasource.DataSourceTransactionManager"	p:dataSource-ref="ds-one" />
	<bean id="dsTwotransactionManager"	class="org.springframework.jdbc.datasource.DataSourceTransactionManager"	p:dataSource-ref="ds-two" />

	<context:component-scan base-package="com.example.service-one, com.example.service-two">
	</context:component-scan>
</beans>

 


이 상태로 어플리케이션을 구동하면 다음과 비슷한 에러가 발생하고 디플로이가 안 될 것이다.

Panel

Ignoring

bean

creation

exception

on

FactoryBean

type

check:

org.springframework.beans.factory.UnsatisfiedDependencyException: 

Error

creating

bean

with

name

'myMapper'

defined

in

file

:

Unsatisfied

dependency

expressed

through

bean

property

'sqlSessionFactory':

No

qualifying

bean

of

type

[org.apache.ibatis.session.SqlSessionFactory]

is

defined:

expected

single

matching

bean

but

found

2:

dsOneSqlSessionFactory,

dsTwoSqlSessionFactory;

 


에러 메시지를 보면 두 개의 SqlSessionFactory 가 지정되어 있다고 표시되어 있다.

원인은 설정의 38 라인부터 42 라인까지 있는 MyBatis 의 MapperScannerConfigurer 의 MapperScannerConfigurer 어떤  SqlSessionFactory 어떤  SqlSessionFactory 를 참조해야 할지 몰라서 발생한다.

 


일단 내가 아는 해결 방법은 두 가지가 있다.


1.@Autowired 대신 @Resource 사용

@Resource(name="dsOneSqlSessionFactory")  처럼 어떤 sessionFactory 를 쓸지 여부를 Java Config

...

사용하여 Mapper 소스마다 지정해 준다. 

...

...



2. sqlSessionFactoryBeanName 으로 명시적으로 지정

MyBatis 의 sqlSessionFactoryBeanName 을 사용해서 다음과 같이 매퍼에

...

사용할 sqlSessionFactoryBeanName

...

명시적으로 지정한다.

Code Block
languagexml
titledatabase-context.xml
linenumberstrue
	
	<bean id="dsOneScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"
		p:basePackage="com.example.mapper-one"
		p:sqlSessionFactoryBeanName="dsOneSqlSessionFactory" />
 
	<bean id="dsTwoScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"
		p:basePackage="com.example.mapper-two"
		p:sqlSessionFactoryBeanName="dsTwoSqlSessionFactory" />