Postgresql 에서는 n 개의 row
에 대해서 insert
, update
, delete
처리를
하는 것과 동시에 처리된 row
들의 정보를 곧바로 조회할 수 있습니다.
이러한 기능을 제공하는 문법이 바로 PostgreSQL 의 Returning
입니다.
간단한 예로 다음과 같은 작업이 가능합니다.
DELETE USER (NAME, PHONE_NUM)
WHERE USER_SIGN_OUT = TRUE
RETURNING *
이렇게 하면 USER
테이블에서 USER_SIGN_OUT=TRUE
에 해당하는 모든
사용자 정보가 삭제되고 마지막에 해당 사용자들에 해당하는 모든 row 정보가 반환됩니다.
비슷한 맥락으로 INSERT
를 하면 생성된 row 를 반환하고,
UPDATE
를 하면 수정된 row 를 반환하게 됩니다.
이제 Returning 이 뭔지 알았으니, MyBatis 에서 활용하는 법을 알아보겠습니다.
insert
, update
, delete
쿼리 모두 사용이 가능합니다.
다만 조심할 것은 반드시 mybatis 의 <select>
태그를 사용해야 된다는 점입니다.
결과적으로 returning *
으로 반환을 받으니 <select>
를 쓰는 게 어찌보면 당연합니다.
<!-- 반드시 select tag 를 사용해야 합니다 -->
<select id="updateConfmAt"
parameterType="dto.AuthorReqstDTO"
resultType="vo.AuthorReqstVO">
UPDATE AUTHOR_REQST
SET
CONFIRM_AT = #{confirmAt},
UPDATE_USR_ID = #{updateUsrId},
UPDATE_DT = NOW()
WHERE REQST_ID = #{reqstId}
returning *
</select>
<select id="insertUser"
parameterType="dto.UserDTO"
resultType="vo.UserVO">
INSERT PLATFORM_USER (NAME, PHONE_NUMBER, AGE)
INTO (#{name}, #{phoneNumber}, #{age})
returning *
</select>
<select id="deleteUser"
parameterType="dto.UserDTO"
resultType="vo.UserVO">
DELETE PLATFORM_USER
WHERE REQST_ID = #{reqstId}
returning *
</select>
returning *
으로 돌려받고 나서 join
을 해야된다면 WITH
절과 함께 사용하면 됩니다.
<select id="ntcnNotSendList"
parameterType="string"
resultMap="reqstResultMap">
WITH A AS (
UPDATE AUTHOR_REQST
SET REQUEST_CONFIRM = true
WHERE
REQUEST_ID = #{reqstId}
RETURNING *
)
SELECT
A.*,
B.USER_EMAIL
FROM A
left join AUTHOR_USER B on A.REQUEST_USER_ID = B.USER_ID
</select>
그런데 가끔은 returning 으로 부분적으로만 데이터를 받고 싶을 수도 있습니다.
그럴 때는 returning *
이 아니라 returning <컬럼명1>, <컬럼명2>, ...
같은
방식으로 반환 받을 수 있습니다.
<select id="insertUser"
parameterType="dto.UserDTO"
resultType="int">
INSERT PLATFORM_USER (NAME, PHONE_NUMBER, AGE)
INTO (#{name}, #{phoneNumber}, #{age})
returning USER_ID
</select>
<!-- 1개 이상을 반환 받을 때는 편하게 map 으로 받아도 됩니다.-->
<!-- 자신만의 Pojo, resultMap 이 있다면 그걸 써도 되고요 -->
<select id="insertUser"
parameterType="dto.UserDTO"
resultType="map">
INSERT PLATFORM_USER (NAME, PHONE_NUMBER, AGE)
INTO (#{name}, #{phoneNumber}, #{age})
returning USER_ID, NAME
</select>
깨달음을 얻었습니다. 정말 감사합니다.