간혹가다 spring + mybatis가 아닌 spring + ibatis 연동을 원하는 분들을 위해 포스팅 하게되었음.
2014/07/22 - [스프링연동하기/spring3 mvc 설정] - 스프링3(Spring3) MVC 연동 (1) - STS 다운로드 및 헬로월드 출력하기
2014/07/22 - [스프링연동하기/spring3 mvc 설정] - 스프링3(Spring3) MVC 연동 (2) - 폼값 전송 + 인코딩 설정
2014/07/22 - [스프링연동하기/spring3 mvc 설정] - 스프링3(Spring3)MVC 연동 (3) - 서버값 웹페이지로 전송하기
2014/07/22 - [스프링연동하기/spring3 mvc 설정] - 스프링3(Spring3) MVC 연동 (4) - 서버에 파일전송
spring 기본 연동이 되었다면 다음과 같이 ibatis 연동을위한 pom.xml설정을 잡아보도록 하자
설명은 MySQL 기준으로 진행함
● POM.xml dependency 추가
<dependency> <groupId>org.apache.ibatis</groupId> <artifactId>ibatis-sqlmap</artifactId> <version>2.3.4.726</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.31</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring-framework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring-framework.version}</version> </dependency>
● resources -> spring -> application-config.xml다 다음과 같은 코드 추가
<context:component-scan base-package="com.spring.web"/> <bean id="dataSource" 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/test" /> <property name="username" value="root" /> <property name="password" value="apmsetup" /> </bean> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation" value="classpath:/sqlmap/sql-map-config.xml"/> <property name="dataSource" ref="dataSource"/> </bean>
● resources -> sql, sqlmap 폴더 생성
● application-config.xml에서 작성한 코드중 sqlMapClient bean의
configLocation이라는 property 속성의 value를 보면 sql-map-config.xml 을
바라보게 되있다.
● resources -> sqlmap 폴더안에 다음 파일을 추가
● resources -> sql 폴더내부에는 쿼리xml 파일들이 존재해야함
샘플파일은 하단에 첨부
※ 각파일들이 추가될때마다 sql-map-config.xml에 리소스 경로 추가해주어야함
● HelloWorldController클래스에 하단에 있는 코드추가
@Autowired private SpringDao dao; @RequestMapping("/ibatisTest") public void ibatisTest(){ try { ArrayList<String> list = dao.ibatisTest(); for(String str : list) { System.out.println(str); } } catch (SQLException e) { e.printStackTrace(); } }
com.spring.web.dao 패키지 생성 후 내부에 SpringDao.java 클래스를 생성
package com.spring.web.dao; import java.sql.SQLException; import java.util.ArrayList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.ibatis.sqlmap.client.SqlMapClient; @Repository public class SpringDao { @Autowired private SqlMapClient sql; @SuppressWarnings("unchecked") public ArrayList<String> ibatisTest() throws SQLException { return (ArrayList<String>)sql.queryForList("sql.showtable"); } }
spring3 + ibatis 연동완료!
트랜잭션은 제외한 샘플링임
트랜잭션 설정을 원한다면 mybatis에 트랜잭션 설정 부분을 참고하시길...
2014/07/25 - [스프링연동하기/spring3 mybatis 설정] - 스프링3(Spring3) - mybatis 연동(2) 트랜잭션설정
ibatis용 다중 db접속에 대한 설정은
2014/07/28 - [스프링연동하기/spring3 mybatis 설정] - 스프링3(Spring3) - mybatis 연동(3) 다중DB 접속 + 트랜잭션 설정
포스팅을 참고하면 되겠지만 추후에 별도로 ibatis용 다중DB접속에 대한 포스팅을 할 예정임
/ibatisTest URL 호출시 화면은 나오지 않을것임
단순 db통신후 데이터를 정상적으로 받을수 있는지 테스트를 하기 위한것일뿐
● 이클립스 콘솔실행 화면
도움이 되셨다면 공감클릭! 궁금하신점은 댓글!!
스프링3(Spring3) - mybatis 연동(3) 다중DB 접속 + 트랜잭션 설정 (6) | 2014.07.28 |
---|---|
스프링3(Spring3) - mybatis 연동(2) 트랜잭션설정 (2) | 2014.07.25 |
스프링3(Spring3) - mybatis 연동(1) (6) | 2014.07.23 |
지난 포스팅에는 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 |
지난 포스팅에 이어서 service 영역에 트랜잭션 처리를 하고자 한다.
2014/07/23 - [스프링연동하기/spring3 mybatis 설정] - 스프링(Spring)3 - mybatis 연동(1)
@transactional인가 어노테이션으로 트랜잭션을 주는 방식도 있긴하지만, xml 설정을 함으로
service영역에서의 트랜잭션 처리를 하고자한다.
현재 방식으로 insert 쿼리 여러개를 선언하고 중간에 오류를 발생시키면 오류나기 전에 있던
데이터들은 insert가 되어진다.
이부분을 막고자 트랜잭션설정을 주려고 한다.
뭐 트랜잭션 신경 안쓰시려고는 분들은 이번 포스팅을 넘기셔도 무관함..
트랜잭션 처리를위한 추가 dependency를 pom.xml에 등록해주도록 하자
<dependency> <groupId>aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.5.3</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>2.1_3</version> </dependency>
기존 mvc-config.xml에 정의해주었던 component-scan을 다음과 같이 변경해주도록 하자
수정전
<context:component-scan base-package="com.spring.web"/>
수정 후
<context:component-scan base-package="com.spring.web" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan>
이어서 application-config.xml에 내용 추가 및 수정을 해주도록 하자
<bean> 태그가 아닌 전체 xml을 감싸고 있는 <beans>태그가 있을 텐데 다음과 같이
변경 해주도록 하자
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
aop 부분과 tx 부분만 추가 되었다.
이제 트랜잭션 설정을 해주도록 하자
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <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:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <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>
위와같이 해주었다면 트랜잭션 설정이 모두 마무리가 되었다.
임의의 테이블을 만들고 트랜잭션 테스트를 해보도록 하자
※ mysql 경우 table type이 innodb여야 트랜잭션처리가 적용이된다.
create table 샘플코드
CREATE TABLE `test` ( `test_column` varchar(5) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8
테이블 생성이 완료 되었다면 이제는 클래스에 controller/service/dao를 추가해주도록 하자
지난 포스팅에는 그냥 web내부에 controller/dao 패키지를 생성하였는데
web 패키지에 추가로 새로운 패키지를 생성하여 내부에 controller/service/dao를 작성하도록 하겠음.
패키지 구성은 다음과 같음.
다음구조와 같이 만들었다면 controller/service/dao 부분에 대하여 샘플 코드를 작성하도록 하자
TestController.java 코드
@Controller public class TestController { @Autowired private TestService service; @RequestMapping(value="/saveQuery") public void saveQuery(){ try { service.saveQuery(); } catch (SQLException e) { e.printStackTrace(); } } }
TestService.java 코드
@Service public class TestService { @Autowired private TestDao dao; 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", "1231111111111111"); dao.saveQuery(map); map = new HashMap<String, String>(); map.put("test", "123"); dao.saveQuery(map); } }
TestDao.java코드
@Repository public class TestDao { @Autowired private SqlSession sql; public void saveQuery(Map<String, String> map) throws SQLException { sql.insert("sql.saveQuery",map); } }
마지막으로 sql.xml에 insert 쿼리 하나를 작성해주도록 하자
<insert id="saveQuery" parameterType="java.util.Map"> INSERT INTO test VALUES(#{test}) </insert>
위의 로직상 설명을 한다면 return 타입은 없어서 우선적으로 웹페이지는 뜨지 않을것이다.
그리고 service 부분에 총 3번의 dao를 호출하는데 test 테이블의 test_column 컬럼의 제한수가
총 5글자가 들어갈수 있다.
즉, 첫번째 insert는 정상적으로 테이블에 등록되고 두번째 insert에는 exception이 발생하여
에러를 웹이랑 콘솔에 뿜을것이다.
그리고는 테이블에 데이터가 등록되지 않은것을 확인 하였다면 정상적으로 트랜잭션 처리가 된것임.
※ 주의할점
application-config.xml 에 tx:advice태그내에 tx:method 가 몇가지 있는데
tx:method의 name을 보면 save* << 이런식으로 주었다.
service의 메서드 시작문구가 save로 시작된다면 트랜잭션 적용을 한다는 의미이다.
만약 본인이 abcTest() << 라는 메서드로 트랜잭션 처리를 하고 싶다면
다음과 같이 태그 추가를 해주면 될것이다.
<tx:method name="abc*" rollback-for="Exception"/>
그리고 service / dao 클래스에 try/catch를 주지말고 throws SQLException 형식으로 처리를
해준다음 controller에서 try{}catch{}로 잡아주어야 할것이다.
★ 추가된 내용 ★
간혹가다가 트랜잭션 처리가 안될경우 mvc-config.xml 에 다음처럼 aop 추가를 해주도록 하자
<aop:config proxy-target-class="true"> <aop:pointcut id="controllerOperation" expression="execution(public * com.spring.web..controller.*Controller.*(..))" /> </aop:config>
도움이 되셨다면 공감클릭! 궁금하신점은 댓글!!
스프링3(Spring3) - ibatis 연동하기 (0) | 2014.08.20 |
---|---|
스프링3(Spring3) - mybatis 연동(3) 다중DB 접속 + 트랜잭션 설정 (6) | 2014.07.28 |
스프링3(Spring3) - mybatis 연동(1) (6) | 2014.07.23 |
이번 포스팅은 spring과 mybatis db 연동을 해볼 예정임
maven에 익숙치 않아서인지 삽질좀 한듯 -0-ㅋㅋㅋ
우선은 pom.xml 에 다음과 같이 dependency들을 추가해주도록 하자
<!-- add maven --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.7</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.31</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring-framework.version}</version> </dependency>
이어서 resources -> spring -> application-config.xml 에 다음과 같이 소스 추가를 하자
<context:component-scan base-package="com.spring.web"/> <bean id="dataSource" 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> <!-- SESSIONFACTORY 설정 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- ibatis와 다르게 sql디렉토리에 xml 추가만 해주면 별도추가없이 알아서 xml내의 쿼리 인식 --> <property name="mapperLocations" value="classpath*:sql/**/*.xml" /> </bean> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg ref="sqlSessionFactory" /> </bean>
그리고 resources내에 sql 폴더를 생성 후 다음 파일을 추가해주자
HelloWorldController클래스에 코드 추가
@Autowired private SpringDao dao; @RequestMapping("/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); } } } } catch (SQLException e) { System.out.println(e.toString()); } }
com.spring.web.dao 패키지 생성 후 내부에 SpringDao.java 클래스를 생성하도록 하자
package com.spring.web.dao; import java.sql.SQLException; import java.util.ArrayList; import java.util.Map; import org.apache.ibatis.session.SqlSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @Repository public class SpringDao { @Autowired private SqlSession sql; @SuppressWarnings("unchecked") public ArrayList<Map<String, Object>> queryTest() throws SQLException { return (ArrayList)sql.selectList("sql.queryTest"); } }
이걸로 jdbc 연동이 끝났다.
완전 심플하지 않은가~~!!
물론 transaction 처리는 제외한 예제이다
위 소스를 실행후 웹페이지에 화면은 나오지 않을것이다.
Console에서 다음 하단 그림과 같이 값이 찍혀 나온다면 정상적으로 출력된다면 db연동은 끝~~
원래는 interface 만들고 implements 받고 해야하는데 귀찮음..
그냥 심플하게 연동만 해보는것임
다음 포스팅은 transaction 관한 설정을 해보도록 하겠음!!
스프링3(Spring3) - ibatis 연동하기 (0) | 2014.08.20 |
---|---|
스프링3(Spring3) - mybatis 연동(3) 다중DB 접속 + 트랜잭션 설정 (6) | 2014.07.28 |
스프링3(Spring3) - mybatis 연동(2) 트랜잭션설정 (2) | 2014.07.25 |