시스템에서 하나의 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를 하게 되었다.
'어장 Develop' 카테고리의 다른 글
[JavaScript] timestamp convert to date type (1) | 2019.03.15 |
---|---|
[Intellij] 인텔리제이 - lombok 설치 (0) | 2018.09.06 |
리눅스 prerouting 설정방법 (1) | 2018.03.15 |
쉘 스크립트 간략정리 - 계속 추가 (0) | 2014.11.28 |
The content of elements must consist of well-formed character data or markup (0) | 2013.06.13 |