이번포스팅은 Spring3 + Mybatis 연동에서 INSERT 쿼리 실행 후
시퀀스값을 가져오는 방법에 대해서 포스팅을 해보도록 하겠습니다.
먼저 시퀀스 자동증가를 지원해주는 MySQL,MSSQL 버전에 대하여 예를 들도록 해보겠습니다.
MySQL의 경우는 자동증가 시켜주고자 하는 컬럼에 auto_increment 옵션을 적용해주고
MSSQL의 경우는 IDENTITY(초기값,증가값) 에 대한 옵션을 적용해주면 되겠습니다.
CREATE TABLE increment ( seq bigint(20) NOT NULL PRIMARY KEY AUTO_INCREMENT, title varchar(100) NOT NULL )
MSSQL에 경우는 상단 쿼리에서 AUTO_INCREMENT 를 IDENTITY(1,1)로 변경해주시면 되겠습니다.
제일먼저 컨트롤러에 들어갈 샘플코드입니다.
@RequestMapping("/savedata") public void savedata(){ try { Map<String, Object> map = new HashMap<String, Object>(); map.put("title", "제목입니다."); studyService.savedata(map); } catch (Exception e) { e.printStackTrace(); } }
이어서 Service interface 부분과 ServiceImpl class 부분 샘플 코드입니다.
public void savedata(Map<String, Object> map) throws SQLException;
@Override public void savedata(Map<String, Object> map) throws SQLException { System.out.println("INSERT직전 시퀀스값이 존재하는지:"+map.get("seq")); dao.savedata(map); System.out.println("INSERT직후 시퀀스값이 존재하는지:"+map.get("seq")); }
이어서 Dao interface와 DaoImpl class 부분에 대한 샘플코드입니다.
public Integer savedata(Map<String, Object> map) throws SQLException;
@Override public Integer savedata(Map<String, Object> map) throws SQLException { return query.insert("query.savedata",map); }
마지막으로 Mybatis INSERT 쿼리 xml 코드부분입니다.
<insert id="savedata" parameterType="java.util.Map" useGeneratedKeys="true" keyProperty="seq"> INSERT INTO increment (title) VALUES(#{title}) </insert>
실행결과를 확인 후 각 설명을 드리도록 하겠습니다.
위와같이 "/savedata" URL 을 호출하여 2번에 데이터 insert처리를 하였습니다.
각 설명을 드리겠습니다.
useGeneratedKeys : 사용하는 DB에서 자체적으로 생성한 키(ex : 자동 증가 컬럼)를 받는옵션입니다.
디폴트는 false이므로 자동증가 값을 받고자 할경우 TRUE로 정의합니다.
keyProperty : INSERT/UPDATE 쿼리에만 적용되는 속성이며 return값으로 보내주고자 하는 컬럼명을 정의해 주면 됩니다.
(대신, vo 혹은 map의 key값과 일치하여야 합니다.)
INSERT 후 자동증가값을 RETURN값으로 가져왔으므로 return으로 ServiceImpl 클래스로 보내주도록 합니다.
DaoImpl에서는 Integer 타입을 return 해주었지만 ServiceImpl부분에서는 별도로 return 값을 받지 않습니다.
이유는 자동적으로 dao.savedata(map); 코드에 넘겨준 map타입에
Mybatis에서 자동적으로 return값을 key mapping을 해주어 담아주었기 때문입니다.
두번째 방법은 오라클을 포함한 모든 DBMS(MySQL,MSSQL,Oracle) 에 적용이 가능합니다.
Service / Dao 영역 코드는 첫번째 방법과 동일하며
쿼리xml부분만 SelectKey태그를 이용하여 return값을 보내주는 방식인대
다음처럼 선택하여 적용하시면 되겠습니다.
<insert id="savedata" parameterType="java.util.Map"> INSERT INTO increment (title) VALUES(#{title}) <selectKey keyProperty="seq" resultType="Integer" order="AFTER"> SELECT LAST_INSERT_ID() </selectKey> </insert>
<insert id="savedata" parameterType="java.util.Map"> INSERT INTO increment (title) VALUES(#{title}) <selectKey keyProperty="seq" resultType="Integer" order="AFTER"> SELECT IDENT_CURRENT('increment') </selectKey> </insert>
MSSQL의 경우 IDENT_CURRENT('테이블명')을 작성해주시면 되겠습니다.
<insert id="savedata" parameterType="java.util.Map"> INSERT INTO seq_test(idx,title) VALUES(idx_test_seq.nextval,#{title}) <selectKey keyProperty="seq" resultType="Integer" order="AFTER"> SELECT seq.currval FROM dual </selectKey> </insert>
Oracle의 경우는 seq는 create sequence 로 생성한 시퀀스.currval을 적용해주시면 되겠습니다.
그럼 SelectKey를 이용한 결과값을 확인해 보도록 하겠습니다.
역시 동일하게 결과값이 출력되었습니다.
insert된 데이터의 시퀀스를 가져오는 경우는
보통 다른 테이블에 외래키 insert하기 위해 사용하기 때문에
알아두시면 좋겠습니다.
by 개발로짜
mybatis와 ibatis별 동적태그 비교문 알아보도록 하자 (5) | 2014.11.17 |
---|---|
mybatis와 ibatis 반복문 비교하기(foreach vs iterate) (0) | 2014.11.17 |