1. selectKey는 오직 insert메소드에서만 사용가능하다.
- insert메소드만이 CRUD구문에서 유일하게 Object를 반환한다.
2. selectKey는 데이터베이스에서 생성되는 키값을 삽입을 완료한 후 알고 싶을때 쓴다.
3. selectKey값의 접근법은 두가지가 있다.
1) 레코드를 삽입하고 데이터베이스가 키를 생성한 후에 생성된 키를 가져오는것
ex) <insert id="insert">
INSERT INTO Account ( username, password ) VALUES #username#, #password#
<selectKey keyproperty="accountId" resultClass="int">
SELECT SCOPE_IDENTITY()
</selectKey>
</insert>
ps : SCOPE_IDENTITY() 함수는 동일한 범위(저장프로시저, 트리거, 일괄처리 등)에서 테이블에 삽입된 마지막 ID값을 반환한다.(MSSQL)
2) 레코드를 추가하기 전에 키를 가져오는법
ex) <insert id="insertSequence">
<selectKey keyProperty="accountId" resultClass="int">
SELECT nextVal(#sequence#)
</selectKey>
INSERT INTO Account ( accountId, username, password )
VALUES ( #accountId#, #username#, #password#)
</insert>
이 두개의 예제는 application의 입장에서 볼때는 구문사이에 차이가 전혀 없다.
(이 예제는 첫번째 접근법에서 SCOPE_IDENTITY()를 사용해서 잠재적인 문제를 최소화한 상태다)
하지만 두개의 접근법은 예외적인 상황에서 차이가 좀 있는데
레코드를 추가하기 전에 키를 가져오는건 일반적으로 가장 안전한 방법이지만
데이터베이스에서 생성된 키를 가져오는것은 기대하는것과 다르게 작동할 수 있다는 잠재적인 문제가 있다.
책에 예로 든 내용으로는 두개의 스레드가 거의 동시에 insert구문을 실행했을때의 예를 들고 있는데
이 문제를 해결하기 위해 첫번째 방법을 사용했을때는 반환된 키값이 내가 원한 insert구문에 의해 생성된
키값인지 확인해보는것이 좋다.
아래는 여러행을 랜덤값을 넣어서 업데이트하는 예제이다.
UPDATE TBCK299 SET
TND_CD = TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS') || '_' || (select LPAD(SUBSTR(ABS(DBMS_RANDOM.RANDOM) || '', 1, 8), 8, '0') from dual)
WHERE TND_CD = #tndCd#
'iBATIS' 카테고리의 다른 글
iBatis에서 질의 작성중 $ Escape 사용법 (0) | 2011.10.07 |
---|