Mybatis 이전버전인 ibatis + Spring3 에 대한 기본적인 연동법을 소개해보고자 합니다.
Spring 기본 연동법은 하단 포스팅을 참조해 주세요
2014/11/06 - [개발에필요한연동법/스프링연동] - STS 이클립스를 이용하여 UTF-8 인코딩 설정 및 Spring3 MVC 연동해보기
2014/11/06 - [개발에필요한연동법/스프링연동] - Spring3 한글깨짐 방지를 위한 UTF-8 인코딩 설정하기
2014/11/14 - [개발에필요한연동법/스프링연동] - Spring3 Maven을 이용하여 pom.xml에 oracle,mysql,mssql jdbc 라이브러리 등록하기
위 링크 기준으로 이어서 DB 설정에 대하여 포스팅 하도록 하겠습니다.
저는 Mybatis 연동법에 소개드렸듯이 MySQL 기준으로 아이바티스 연동을 하도록 하겠습니다.
2014/11/14 - [개발에필요한연동법/스프링연동] - Spring3 + MyBatis 기본설정 + 연동테스트 후 쿼리로그 확인해보기
/resources/spring/application-config.xml 설정부분을 보도록 하겠습니다.
<context:component-scan base-package="com.spring"/> <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://도메인:포트/db명" /> <property name="username" value="계정" /> <property name="password" value="비밀번호" /> </bean> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation" value="classpath:sqlmap-config.xml"/> <property name="dataSource" ref="dataSource"/> </bean> </beans>
위와같이 설정을 하셨다면
"/resources/sqlmap-config.xml 파일을 하나 생성하고 다음 코드를 덮어씌워주세요
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd"> <sqlMapConfig> <settings cacheModelsEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="true" useStatementNamespaces="true" /> <sqlMap resource="query/query.xml" /> </sqlMapConfig>
"/resources/query/" 디렉토리 생성 후 query.xml파일을 생성 한 다음
하단 코드를 덮어씌워보도록 하겠습니다.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd"> <sqlMap namespace="query"> <select id="ibatisSelect" resultClass="String"> SELECT 'TEST' </select> </sqlMap>
이번 포스팅은 간단하게 DB SELECT 테스트를 하기 위함으로써 Service 영역을 제외하고
Controller -> Dao 로 바로 호출하는 샘플 코드를 작성해보겠습니다.
@Autowired private StudyDao studyDao; @RequestMapping("/ibatisSelect") public void ibatisSelect(){ try { studyDao.ibatisSelect(); } catch (Exception e) { e.printStackTrace(); } }
public void ibatisSelect() throws SQLException;
@Repository public class StudyDaoImpl implements StudyDao { @Autowired private SqlMapClient query; public void ibatisSelect() throws SQLException { String result= (String)query.queryForObject("query.ibatisSelect"); System.out.println("결과값:"+result); } }
샘플코드들에 대한 작성이 완료되었다면 한번 실행결과를 확인해보도록 하겠습니다.
쿼리로그는 Mybatis와 다르게 출력되지않지만 결과값이 나왔다는 것은 Spring과 ibatis 와 연동이 되었다는 결과 입니다.
다음장은 logback.xml 파일로 쿼리출력을 하는것이 아닌
log4j 를 이용하여 쿼리로그 출력하는 포스팅을 하도록 하겠습니다 .
그다음 이어서 스프링 + 아이바티스 기본 연동에 추가로 트랜잭션 관련 포스팅을 다루겠습니다.
by 개발로짜
Spring3 MVC + HttpClient를 이용하여 GET/POST/Multipart API 웹서버 구축해보기 (2) | 2014.12.07 |
---|---|
Spring3 spring-task를 이용하여 스케줄러 연동 및 동작시켜보기 + DB연동(MySQL기준) (0) | 2014.11.24 |
Spring3 + Mybatis 여러개 Datasource 연동법(다중 트랜잭션 포함) (0) | 2014.11.16 |
Spring3 + Mybatis연동에 추가로 트랜잭션 설정 하여 실패시 Rollback 처리하기 (2) | 2014.11.14 |
Spring3 + MyBatis 기본설정 + 연동테스트 후 쿼리로그 확인해보기 (8) | 2014.11.14 |
이번에 다루고자 하는 Spring + Mybatis 포스팅은 다중DB 설정에 대하여 작성해보도록 하겠습니다.
SqlSession 객체에 "@Resource" 어노테이션을 이용하여 Datasource 구분을 지어 여러개의 DB 호출이 가능합니다.
이전 Mybatis 연동설정법은 다음 포스팅을 참고해주세요
2014/11/14 - [개발에필요한연동법/스프링연동] - Spring3 Maven을 이용하여 pom.xml에 oracle,mysql,mssql jdbc 라이브러리 등록하기
2014/11/14 - [개발에필요한연동법/스프링연동] - Spring3 + MyBatis 기본설정 + 연동테스트 후 쿼리로그 확인해보기
2014/11/14 - [개발에필요한연동법/스프링연동] - Spring3 + Mybatis연동에 추가로 트랜잭션 설정 하여 실패시 Rollback 처리하기
@Resource 어노테이션을 위해서는 pom.xml에 하단 dependency를 추가해주도록 합니다.
<dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.2</version> </dependency>
기존 application-config.xml 내에 Datasource 설정코드가 하나 설정 되어있었습니다.
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="드라이버클래스" /> <property name="url" value="jdbc:mysql://도메인:포트/db명" /> <property name="username" value="계정" /> <property name="password" value="패스워드" /> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath*:query/**" /> </bean> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg ref="sqlSessionFactory" /> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <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="delete*" rollback-for="Exception"/> </tx:attributes> </tx:advice>
기존 설정되어있는 위 4가지 bean 태그와 tx:advice 태그를 복사하여 붙여넣기를 합니다.
각 태그들의 id / ref를 변경해주도록 합니다.
추가로 tx:advice 의 transaction-manager속성같을 변경합니다.
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="드라이버클래스" /> <property name="url" value="jdbc:mysql://도메인:포트/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*:query/**" /> </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="delete*" rollback-for="Exception"/> </tx:attributes> </tx:advice>
기존 aop:config 태그내에 다음 태그 추가를 해주도록 합니다.
<aop:advisor id="transactionAdvisor2" pointcut-ref="serviceOperation" advice-ref="txAdvice2"/>
본인이 사용하고자 하는 db의 가상호출 테이블은 다음과 같습니다.
위 테이블의 COUNT 쿼리를 실행하여 콘솔창에 카운트 수를 출력해보고자 합니다.
위처럼 각 테이블마다 카운트가 이클립스 콘솔창에 동일하게 출력된다면 mybatis 다중 db 연동이 성공한 것일 겁니다.
Controller/Service/Dao 부분 샘플코드를 작성해보도록 합니다.
@RequestMapping("/multipledb") public void multipledb(){ try { studyService.multipledb(); } catch (SQLException e) { e.printStackTrace(); } }
public void multipledb() throws SQLException;
public void multipledb() throws SQLException { dao.multipledb1(); dao.multipledb2(); }
public void multipledb1() throws SQLException; public void multipledb2() throws SQLException;
public void multipledb1() throws SQLException { int count = query.selectOne("query.multipledb1"); System.out.println("test.mybatis_table COUNT 결과:"+count); } public void multipledb2() throws SQLException { int count = query2.selectOne("query.multipledb2"); System.out.println("sample.grid_sample COUNT 결과:"+count); }
DaoImpl 기존 Sqlsession 인터페이스부분을 다음처럼 변경을 해줍니다.
@Autowired @Resource(name="sqlSession") private SqlSession query; @Autowired @Resource(name="sqlSession2") private SqlSession query2;
마지막 query.xml에 다음 코드를 추가로 결과 확인을 해보도록 하겠습니다.
<select id="multipledb1" resultType="Integer"> SELECT COUNT(*) FROM mybatis_table </select> <select id="multipledb2" resultType="Integer"> SELECT COUNT(*) FROM grid_sample </select>
위처럼 @Resource 어노테이션별로 실행한 결과를 콘솔상에서 확인이 되었습니다.
실행결과, 상단 DB툴에서 조회한 COUNT 갯수와 동일한 결과가 나온것을 확인 할 수 있었습니다.
by 개발로짜
Spring3 spring-task를 이용하여 스케줄러 연동 및 동작시켜보기 + DB연동(MySQL기준) (0) | 2014.11.24 |
---|---|
Spring3 + ibatis(아이바티스) 연동해보고 쿼리결과값 콘솔에 출력해보기 (5) | 2014.11.17 |
Spring3 + Mybatis연동에 추가로 트랜잭션 설정 하여 실패시 Rollback 처리하기 (2) | 2014.11.14 |
Spring3 + MyBatis 기본설정 + 연동테스트 후 쿼리로그 확인해보기 (8) | 2014.11.14 |
Spring3 Maven을 이용하여 pom.xml에 oracle,mysql,mssql jdbc 라이브러리 등록하기 (0) | 2014.11.14 |
이번 포스팅은 Mybatis 기본 연동법에 추가로 트랜잭션 설정을 잡아주고자 합니다.
MySQL 기준으로 설명합니다.
테이블은 각 DBMS에 맞추어 CREATE 해보시면 되겠습니다.
테이블을 생성해보도록 하겠습니다.
CREATE TABLE mybatis_table ( title VARCHAR(100) NOT NULL ) ENGINE=INNODB DEFAULT CHARSET=utf8
※ MySQL은 트랜잭션적용을 해주기 위해서는 engine 을 INNODB로 설정을 잡아주셔야 트랜잭션 처리가 가능합니다.
트랜잭션은 여러개 데이터에대한 CRUD 처리 시 하나라도 실패하면 이전에 등록,수정,삭제된 데이터를 모두 롤백 시켜주는 기능입니다.
"나는 그냥 실패직전에 데이터는 그냥 처리하고 실패된 데이터는 수정해서 다시 DB처리할껀대?"
라고 생각하시는분들은 이번 포스팅을 그냥 넘어가주셔도 되겠습니다.
소규모 프로젝트에서 프레임워크 설정을 보면 트랜잭션 설정을 해주지 않은 프로젝트가 꽤 있었습니다.
이럴경우 데이터가 꼬이거나 직접 db에 접속해서 일일이 수정/삭제 해주는 작업을 하니
일관성있게 트랜잭션 설정을 필수로 해주어야 한다고 본인은 생각합니다.
이전 코드에 이어서 Mybatis 트랜잭션 설정을 잡아주도록 해보겠습니다.
2014/11/14 - [개발에필요한연동법/스프링연동] - Spring3 + MyBatis 기본설정 + 연동테스트 후 쿼리로그 확인해보기
service 영역에 "@Transactional" 어노테이션을 적용하여 트랜잭션처리를 해주는 방법이 있던대
이방법에 대해서는 코드를 작성해줄때마다 필요한 메서드에 설정을 해주어야 합니다.
하지만 저는 어노테이션을 이용한 트랜잭션 설정은 하지 않고
직접 application-config.xml 파일에 트랜잭션 설정을 잡아주도록 하겠습니다.
pom.xml에 다음 라이브러리를 추가해주도록 하겠습니다.
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.4</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>3.1</version> </dependency>
mvc-config.xml 파일내에 "context:component-scan" 태그를 다음처럼 재작성해주세요
<context:component-scan base-package="com.spring" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan>
application-config.xml 파일내에 "beans" 태그에 다음 속성을 추가해줍니다.
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
beans 태그 속성중 xsi:schemaLocation 속성값내에 다음 URL을 추가 작성해주도록 합니다.
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
beans 태그 내에 다음 태그를 추가해주도록 합니다.
<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..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="delete*" rollback-for="Exception"/> </tx:attributes> </tx:advice>
상단 "tx:advice" 태그내 "tx:method"태그의 name은
service영역내에 트랜잭션을 처리하고자 하는 메서드명을 정의해주는 겁니다.
인터셉터 URL 지정해주는 것과 비슷한 개념입니다.
2014/11/12 - [개발에필요한연동법/스프링연동] - Spring3 인터셉터와 세션을이용하여 로그인 처리해보기
Service 패키지를 생성 후 다음 템플릿 코드를 작성해주도록 합니다.
public interface StudyService { public void saveTest() throws SQLException; }
@Service public class StudyServiceImpl implements StudyService { @Autowired private StudyDao dao; @Override public void saveTest() throws SQLException { dao.saveTest("글등록테스트1"); dao.saveTest(null); } }
※ DAO 클래스에 "@Repository" 어노테이션이 필수선언이라면
Service 클래스에는 "@Service" 어노테이션을 필수로 설정해주셔야 합니다.
이어서 컨트롤러에 다음 코드를 추가 작성합니다.
@Autowired private StudyService studyService;
@RequestMapping("/saveTest") public void saveTest(){ try { studyService.saveTest(); } catch (Exception e) { e.printStackTrace(); } }
전에 생성했던 Dao/DaoImpl 에 다음코드를 추가합니다.
public void saveTest(String value) throws SQLException;
@Override public void saveTest(String value) throws SQLException { query.insert("query.saveTest",value); }
이어서 query.xml에 insert 쿼리문을 작성합니다.
<insert id="saveTest" parameterType = "String"> INSERT INTO mybatis_table(title) VALUES(#{value}) </insert>
이전 DB연동 포스팅과 다른점이 있다면 이전에는 Controller -> Dao를 바로 호출 하는 형식이었는데
트랜잭션을 Service단에 묶어서 재작성하였습니다.
Conroller -> Service -> Dao 이러한 구조로 진행이 되는데
트랜잭션 처리를 위해 Service부분에 같은 Dao메소드를 2번 호출해주었습니다.
하나는 제대로된 값을 set, 나머지는 NULL값을 INSERT하도록 진행하였습니다.
샘플테이블 제작한 TITLE 컬럼을 확인하면 NOT NULL이므로
마지막 NULL값이 INSERT될시 에러를 출력시키면서 롤백이 되어야합니다.
정상적으로 롤백이 될지 컨트롤러 호출을 브라우저로 해보도록 하겠습니다.
다음과같이 "Column 'title' cannot be null" Exception을 발생 시켰습니다.
한번 DB에 데이터가 등록되어있나 확인해보도록 하겠습니다.
우선 트랜잭션이 처리되었는지 데이터가 들어가지 않았습니다.
그럼 Service의 메서드명을 변경하여 트랜잭션 설정을 적용시켜보지 않도록 하겠습니다.
기존 StudyService / StudyServiceImpl 에 정의한 saveTest() 메소드를 insertTest() 로 변경해주고
컨트롤러의 saveTest() 메소드 내에 정의한
"studyService.saveTest();" -> "studyService.insertTest();"
로 변경을 해주고 서버재시작 후 ,
컨트롤러를 재실행 해보도록 합니다.
같은 Exception이 발생이 되고 DB의 데이터는 다음처럼 Exception 발생전 insert된 데이터가 추가된 것을 확인 할 수 있습니다.
※ insertTest 메서드에 트랜잭션을 적용하고 싶다면 tx:method에 name명을 등록해주면 되겠습니다.
by 개발로짜
Spring3 + ibatis(아이바티스) 연동해보고 쿼리결과값 콘솔에 출력해보기 (5) | 2014.11.17 |
---|---|
Spring3 + Mybatis 여러개 Datasource 연동법(다중 트랜잭션 포함) (0) | 2014.11.16 |
Spring3 + MyBatis 기본설정 + 연동테스트 후 쿼리로그 확인해보기 (8) | 2014.11.14 |
Spring3 Maven을 이용하여 pom.xml에 oracle,mysql,mssql jdbc 라이브러리 등록하기 (0) | 2014.11.14 |
Spring3 인터셉터와 세션을이용하여 로그인 처리해보기 (2) | 2014.11.12 |