지난 포스팅에는 SPRING + MYBATIS 접속 및 트랜잭션 설정에 대한 포스팅을 하였음
2014/07/23 - [스프링연동하기/spring3 mybatis 설정] - 스프링3(Spring3) - mybatis 연동(1)
2014/07/25 - [스프링연동하기/spring3 mybatis 설정] - 스프링3(Spring3) - mybatis 연동(2) 트랜잭션설정
이번시간에는 다중 DB 접속 및 트랜잭션 처리를 설명하고자 한다.
( 설정이 정상 작동하지만 100% 옳은 방법이라고는.... )
해당 포스팅은 DBMS 종류가 틀리더라도 접속이 가능하며 트랜잭션 DBMS 종류와 무관하게 적용이 된다.
우선은 sqlsession에 대한 구분을 위한 어노테이션(@Resource)을 주어야 하므로 필요한
라이브러리 등록을 위해 pom.xml에 다음 dependency를 추가하도록 하자
<dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.2</version> </dependency>
여러 dbms를 사용하려면 oracle/mssql 등 라이브러리를 pom.xml에 등록하여야 하는데 본인은 mysql의 db명만 바꿔서 연동을 할것이므로
다른 라이브러리가 필요하신 분들은 dbms 종류에 따라 라이브러리를 등록하도록 하자.
mssql jdbc 라이브러리등록과 oracle jdbc의 pom.xml dependency등록은 다음 포스팅때 등록한후 링크 걸도록 하겠음.
다음으로 application-config.xml에 기존설정에 추가로 다음 태그를 추가하도록 하자
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/db명" /> <property name="username" value="아이디정보" /> <property name="password" value="비밀번호" /> </bean> <bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource2" /> <property name="mapperLocations" value="classpath*:sql/**/*.xml" /> </bean> <bean id="sqlSession2" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg ref="sqlSessionFactory2" /> </bean> <bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource2"/> </bean> <tx:advice id="txAdvice2" transaction-manager="transactionManager2"> <tx:attributes> <tx:method name="save*" rollback-for="Exception"/> <tx:method name="update*" rollback-for="Exception"/> <tx:method name="remove*" rollback-for="Exception"/> </tx:attributes> </tx:advice>
그냥 기존 태그 Ctrl + C/V 해서 추가한다음 id값과 ref 값만 변경해주면 된다.
기존 값중에 뒤에 2만 추가로 붙여주고 datasource의 정보만 변경하였다.
마지막으로 aop:config 태그내의 aop:advisor태그를 추가해주도록 하자
그럼 aop:config태그의 값은 다음과 같이 될것임
<aop:config proxy-target-class="true"> <aop:pointcut id="serviceOperation" expression="execution(public * com.spring.web..service.*Service.*(..))" /> <aop:advisor id="transactionAdvisor" pointcut-ref="serviceOperation" advice-ref="txAdvice"/> <aop:advisor id="transactionAdvisor2" pointcut-ref="serviceOperation" advice-ref="txAdvice2"/> </aop:config>
이걸로 다중 db접속 및 dbms 전체 트랜잭션이 완료되었다.
기존 같은 쿼리를 이용하여 다른 db에 접속이 되는지 먼저 확인하도록 하자
기존에는
@Autowired private SqlSession sql;
와같이 되었지만
data resource가 두가지로 추가되어서 서버 시작시, 오류가 발생할것이다
application-config.xml의 bean태그중, 클래스가 org.mybatis.spring.SqlSessionTemplate 의 아이디를 설정을 해주어야 한다 .
다음과 같이 두개의 sqlsession을 만든후 resources 어노테이션으로 명칭을 구분해주도록 하자
@Autowired @Resource(name="sqlSession") private SqlSession sql; @Autowired @Resource(name="sqlSession2") private SqlSession sql2;
다음으로는 같은 쿼리를 호출하는 메서드 2개를 만들도록 하자
(기존 show tables 쿼리를 실행하는 쿼리 xml 호출하는것임)
@SuppressWarnings("unchecked") public ArrayList<Map<String, Object>> queryTest() throws SQLException { return (ArrayList)sql.selectList("sql.showtable"); } @SuppressWarnings("unchecked") public ArrayList<Map<String, Object>> queryTest2() throws SQLException { return (ArrayList)sql2.selectList("sql.showtable"); }
그렇다면 기존 /queryTest 컨트롤러내의 다음과같이 변경을 해보도록 하자
@RequestMapping(value="/queryTest") public void queryTest(){ try { ArrayList<Map<String, Object>> list = dao.queryTest(); if(list != null && list.size() > 0){ for(Map<String, Object> map : list) { Set key = map.keySet(); for (Iterator iterator = key.iterator(); iterator.hasNext();) { String keyName = (String) iterator.next(); String valueName = (String) map.get(keyName); System.out.println(keyName +" = " +valueName); } } } System.out.println("==============================="); ArrayList<Map<String, Object>> list2 = dao.queryTest2(); if(list2 != null && list2.size() > 0){ for(Map<String, Object> map : list2) { Set key = map.keySet(); for (Iterator iterator = key.iterator(); iterator.hasNext();) { String keyName = (String) iterator.next(); String valueName = (String) map.get(keyName); System.out.println(keyName +" = " +valueName); } } } } catch (Exception e) { e.printStackTrace(); } }
한번 코드를 실행해보도록 하자
※ 실행화면
설정 DB내의 테이블이 콘솔에 정상적으로 찍혀서 나왔다면 다중 DB 설정이 완료된것임.
이번엔 트랜잭션 처리도 확인해보도록 하자
설정 DB에 다음 테이블을 각각 생성해보도록 하자
(기존 /saveQuery 테이블과 동일)
CREATE TABLE `test` ( `test_column` varchar(5) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8
controller - service - dao - query xml까지 다음과 같이 만들어 보도록하자
controller
@RequestMapping(value="/saveQuery") public void saveQuery(){ try { service.saveQuery(); } catch (SQLException e) { e.printStackTrace(); } }
service
public void saveQuery() throws SQLException { Map<String, String> map = null; map = new HashMap<String, String>(); map.put("test", "123"); dao.saveQuery(map); map = new HashMap<String, String>(); map.put("test", "123"); dao.saveQuery(map); map = new HashMap<String, String>(); map.put("test", "123"); dao.saveQuery(map); map = new HashMap<String, String>(); map.put("test", "123"); dao.saveQuery2(map); map = new HashMap<String, String>(); map.put("test", "998"); dao.saveQuery2(map); map = new HashMap<String, String>(); map.put("test", "123"); dao.saveQuery2(map); }
dao
public void saveQuery(Mapmap) throws SQLException { sql.insert("sql.saveQuery",map); } public void saveQuery2(Map map) throws SQLException { sql2.insert("sql.saveQuery",map); }
query xml
<insert id="saveQuery" parameterType="java.util.Map"> INSERT INTO test VALUES(#{test}) </insert>
위 예로는 정상적으로 2개의 테이블에 데이터가 정상적으로 들어갈것이고, service에서
map.put -> value값을 5자 이상주게되면 오류발생하여 테이블 두군대에 모두 데이터가 롤백되는것을 확인할 수 있을것이다.
도움이 되셨다면 공감클릭! 궁금하신점은 댓글!!
스프링3(Spring3) - ibatis 연동하기 (0) | 2014.08.20 |
---|---|
스프링3(Spring3) - mybatis 연동(2) 트랜잭션설정 (2) | 2014.07.25 |
스프링3(Spring3) - mybatis 연동(1) (6) | 2014.07.23 |