Spirng 3.1.1 + MyBatis + jQuery 사이트를 구현하고 있다.


그런데 현재 시스템에서 서로 다른 2개의 DB 사용을 하고 있는 상태이다

물론 한쪽 DB 접속해서 소유권을 명시적으로 기술해서 DB 테이블에 대한 작업을 진행할 있지만 

일단 datasource 2개를 별도로 만들기로 했다. 다만 Spring 설정은 pure java 설정으로 진행했다.


방법을 찾기 위해 구글과 네이버를 통해 검색을 해보았지만 springboot 대해서는 pure 자바 설정에 대한 자료가 많은 반면 

Spring 대해서는 아직까지도 대부분의 설정이 xml 파일을 이용해서 이루어지고 있었다

게다가 springboot JPA + Hibernate밖에 보이질 않아서 MyBatis 설정은 찾기가 힘들었다.


물론 내가 Spring 원리에 통달해있다면 xml 설정으로부터 java 설정을 이끌어낼 잇었겠지만.


결국 springboot 설정을 설명해놓은 블로그를 참조로하여 설정을 마칠 있었다.



Spring + MyBatis 사용 java 설정을 이용하여 datasource 2 사용하기


1. 먼저 config.java 어떻게 구성하느냐는 개인의 취향일 있을 같다

    나는 각각의 datasource 해당하는 설정 java 별도로 만들었다. 편의성 DSConfigFirst.java DSConfigSecond.java라 하자.


2. 각각의 설정 java 파일에 필요한 annotation @Bean 구현한다다음 3가지 메소드를 구현했다.

   dataSource() : DataSource 리턴

   transactionManager : DataSourceTransactionManager 리턴

   sqlSessionFactory() : SqlSessionFactory 리턴


여기까지 했을 빌드 다음  오류가 발생하였다.

No unique bean of type [org.apache.ibatis.session.SqlSessionFactory] is defined:…


No unique bean of type [org.springframework.transaction.PlatformTransactionManager] is defined:…


각각 SqlSessionFactory PlatformTransactionManager 2 이상 존재한다는 의미였고 것은 2개의 설정이 존재하다보니 설정들을 가져다 사용하는 mapper service에서 어떤 것을 사용할지 몰라 발생하는 오류였던 것이다.


그렇다면 해결책은 mapper service에서 각각 자신이 가져다 사용할 설정을 구분할 있도록 해주면 되는 것이다.


1. SqlSessionDactory 구분

  각각의 설정 java 파일의 @MapperScan annotation sqlSessionFactoryRef 속성을 주고 값으로 각각 다른 이름을 지정해준다.


...

@Configuration

@MapperScan(basePackages = "com.dbfirst.mapper", sqlSessionFactoryRef = "dbFirstSqlSessionFactory")

class DSConfigFirst {

...

}


...

@Configuration

@MapperScan(basePackages = "com.dbsecond.mapper"sqlSessionFactoryRef = "dbSecondSqlSessionFactory")

class DSConfigSecond {

...

}


2. PlatformTransactionManager 구분

  transactionManager() 메소드의 @Bean annotation name 속성을 통해 각각 별도의 이름을 설정해 주고 Service(ServiceImpl) 

  @Transactional   annotation value 속성으로 @Bean name 설정한 이름을 지정해준다.


...

@Configuration

@MapperScan(basePackages = "com.dbfirst.mapper"sqlSessionFactoryRef = "dbFirstSqlSessionFactory")

class DSConfigFirst {

    ...

    @Bean(name="dbFirstTX")
    public PlatformTransactionManager transactionManager() {
        ...
    }
    ... 
}

@Service
@Transactional(value="dbFirstTX")
class DbFirstServiceImpl implements DbFirstService {
    ...
}



...

@Configuration

@MapperScan(basePackages = "com.dbsecond.mapper"sqlSessionFactoryRef = "dbSecondSqlSessionFactory")

class DSConfigSecond {

    ...

    @Bean(name="dbSecondTX")
    public PlatformTransactionManager transactionManager() {
        ...
    }
    ... 
}

@Service
@Transactional(value="dbSecondTX")
class DbSecondServiceImpl implements DbSecondService {
    ...
}


일단 여기까지 하니 정상적으로 2개의 datasource 이용할 있게 되었다.

블로그 이미지

마즈다

이제 반백이 되었지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^