시스템에서 하나의 Unique Value를 여러테이블에 Insert 하는 경우가 생긴다. 간단하게 게시판을 예로 들 수 있는데, 글 작성과 첨부파일이 있는 경우다.

글 내용과 제목, 작성자 정보등을 담는 board_table과 첨부파일만을 저장하는 file_table 이라고 예시를 들어보자. board_table은 글 번호(PK)가 있을 것이고 이 글 번호로 join이 걸리는 file_table의 key_column 이 있다. 하나의 글에는 여러개의 파일이 첨부가 될 수 있다.


board_table의 글번호는 아주 특수한 경우가 아니고서야 Unique로 가져간다. 그리고 글을 작성할 때, Insert 쿼리를 쓰며, 일일히 글번호를 만들어주기 귀찮고 무엇보다 크나큰 오류가 생기는 경우가 있을 수 있으므로 아래와 같이 대부분 sql의 sequence를 이용해 글번호를 유일하게 가져간다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<insert id="QID_INSERT_BOARD" parameterType="hashMap">
    INSERT INTO board_table
    ( 
        board_no -- 글 번호
        , title    -- 글 제목        
        , content -- 글 내용
        , insert_date -- 작성일시
        , insert_user -- 작성자
    )
    VALUES
    (
        seq_board_no.NEXTVAL -- 글번호를 가져오는 시퀀스
        , #{TITLE}
        , #{CONTENT}
        , #{INSERT_DATE}
        , #{INSERT_USER}
    )
</insert>
cs


이 때, 해당 글번호로 작성된 파일들의 파일첨부는 어떻게 Key를 가져와야 할까? 위의 쿼리는 글이 작성되는 시점(insert query가 commit이 되는 시점)에서 글 번호를 생성한다. 쿼리를 날리기 직전에 sequence를 호출, 이를 board_table과 file_table에 key_parameter로 insert 하는 방법도 있겠지만 권장하는 방법은 아니다. 만약, 랜덤키를 쿼리 내에서 생성하는 경우에는? 그렇다면 Key를 쿼리 수행 전에 가져올 수도 없다. 이럴 때 사용하는 것이 ibatis(mybatis)의 펑션인 select key 이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<insert id="QID_INSERT_BOARD" parameterType="hashMap">
    INSERT INTO board_table
    ( 
        board_no -- 글 번호
        , title    -- 글 제목        
        , content -- 글 내용
        , insert_date -- 작성일시
        , insert_user -- 작성자
    )
    VALUES
    (
        seq_board_no.NEXTVAL -- 글번호를 가져오는 시퀀스
        , #{TITLE}
        , #{CONTENT}
        , #{INSERT_DATE}
        , #{INSERT_USER}
    )
    <selectKey keyProperty="BOARD_NO" resultType="int" order="AFTER">
        SELECT seq_board_no.CURRVAL FROM dual
    </selectKey>
</insert>
cs


사용법은 심플하다. insert 쿼리를 실행하기 전에 가져올 것인지 혹은 후에 가져올 것인지에 따라 selectKey의 위치가 Insert 쿼리의 앞 혹은뒤로 옮겨진다. 이 쿼리에서는 Insert를 수행 후에 가장 최근 sequence를 가져올 것이므로, Insert 쿼리의 뒤에 배치했다.

Insert 쿼리가 수행된 후에 selectKey 구문이 실행될 것이고, 조회된 sequence 값이 BOARD_NO 에 세팅, 이후에 사용할 수 있게 된다. 파라미터는 다음과 같다.


Parameter 

설명 

 keyProperty

selectKey가 수행된 이후에 결과값이 세팅되는 key값. 

 resultType

selectKey가 수행된 결과값의 type. string 이라거나 int 라거나...

 order

BEFORE 혹은 AFTER로 설정 가능. selectKey 구문을 먼저(BEFORE) 실행 할 것인지 혹은 나중에(AFTER) 실행할 것인지를 지정한다.


위의 쿼리는 종합적으로 Insert 구문이 실행된 후, sequence가 nextVal이 된 상태이며, 이 상태값을 바로 selectKey가 currval을 통회 최근 sequence 값을 조회, 이후 이 리턴값을 받아 쓰면 되는 구조이다.


덕분에 board_table에 Insert를 수행한 이후, 해당 board_no를 바로 리턴받고 file_table에 Insert를 하게 되었다.

블로그 이미지

김생선

어장에서 바라보는 세상

티스토리 툴바