예를 들어 쿼리 작업을 진행하보면 먼저 쿼리 한줄을 INSERT 을 하고 INSERT 된 구문의 증가된 키 값을 가지고 와서 다음 쿼리에서 바로 사용해야 할 경우가 있다.
이때 mybatis에서 제공해주는 selectKey를 사용 하면 된다.
selectKey를 이용하면 별도로 해당 키 값을 select 하는 구문을 등록할 필요 없이 selectKey 구문에서 해결할 수 있다.
--mysql, mariaDB
create table Board(
rno int not null auto_increment,
boardNo varchar(20) not null,
title varchar(50) not null,
content text not null,
primary key(rno),
unique(boardNo)
);
--oracle의 경우
create table Board(
rno int not null,
boardNo varchar2(20) not null,
title varchar2(50) not null,
content text not null,
primary key(rno),
unique(boardNo)
);
테이블의 PK가 시퀀스로 1 씩 자동 증가 하는 컬럼(rno)이 존재한다 가정하자.
CREATE SEQUENCE rno_seq START WITH 1 INCREMENT BY 1 MAXVALUE 100 CYCLE NOCACHE;
1. 입력하기 전에 특정한 값을 가져온 다음, 그 값을 통해서 처리하고 싶은 경우
boardNo값을 기존에 최대값에 +1한 다음에 그 값을 입력하고 싶다면 아래의 같이 처리
<insert id="insertBoard" parameterType="Board">
<selectKey resultType="string" keyProperty="boardNo" order="BEFORE">
SELECT MAX(boardNo)+1 FROM board
</selectKey>
INSERT INTO board(rno, boardNo, title, content)
VALUES(rno_seq.NEXTVAL ,#{boardID}, #{title}, #{content})
</insert>
<selectKey>구문을 <insert>구문에 넣어준다. resultType은 해당 컬럽의 타입을 정해주면 된다.
keyProperty는 컬럼명이다. Board 클래스에서는 boardNo가 setter, getter메소드가 존재해야 한다.
(getBoard(), setBoardID())
order는 해당 쿼리의 순서를 의미하다. BEFORE라면 insert쿼리문 수행전에 selectKey가 실행된다.
위에서는 기존의 boardNo를 가져오는 부분이기 때문에 당연히 order=BEFORE를 사용했다.
2. 방금 입력한 값의 특정값을 리턴해주고 싶은 경우
만약, 입력한후에 입력된 값의 컬럼값(자동증가값)을 가져오고 싶다면 아래와 같이 진행한다.
SELECT LAST_INSERT_ID()은 mysql(mariadb)에서 사용한다.
방금입력한 테이블의 auto_increment로 증가된 컬럼값을 가져오는 쿼리이다. order=AFTER로 설정한다.
따라서 아래처럼 xml에 추가해주면 된다.
오라클처럼 시퀀스를 별도록 등록해주어야 하는 경우
--oracle의 경우
<insert id="insertInfo" parameterType="Board">
INSERT INTO Board(rno, boardNo, title, content)
VALUES(rno_seq.NEXTVAL, #{boarNo}, #{title}, #{content})
<selectKey keyProperty="rno" resultType="Integer" order="AFTER">
SELECT rno_seq.currval FROM dual
</selectKey>
</insert>
-- mysql(mariaDB) 일 경우
<insert id="insertInfo" parameterType="Board">
INSERT INTO board(boardNo, title, content)
VALUES(#{boarNo}, #{title}, #{content})
<selectKey resultType="int" keyProperty="rno" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
</insert>
이때, 리턴값은 parameterType에 넘겨준 객체에 넘어간다. 즉, 위에서는 이 메소드를 호출한 클래스에서 파라미터로 넘긴 board에서 바로 board.getIq()로 해당값을 가져올 수 있다.
이처럼 selectKey를 사용하려면 applicationContext.xml에서 아래처럼 BATCH 기본설정부분이 주석처리되거나 없어야 한다 (없앤다고 배치가 안되는 것은 아니다. 다만 아래처럼 하면 모든 insert,update,delete가 배치형태로 진행이 된다)
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
<!--<constructor-arg index="1" value="BATCH" /> -->
</bean>
이렇게 하지 않으면 값을 가져오는 부분에서 모두 -2147482646 로 처리되면서 원하는 값을 얻어오지 못하게 된다.
'Java' 카테고리의 다른 글
MyBatis foreach를 이용한 배열 파라미터 삽입하기 (0) | 2021.02.13 |
---|