selectkey를 사용하여 키를 생성하면서 CUD 작업을 진행할 경우 생성한 key를 가져오지 못하는 경우가 있습니다. 

 

이 경우 간단한 이유인데요 보통 개발하실 때 복사하기 붙여 넣기만 하다가 해당 기능의 각 속성들의 기능을 잘 파악하지 못하여 발생하는 문제입니다. 

 

 

<insert id="queryId" parameterType="java.util.Map">
<selectKey keyProperty="id" resultType="java.lang.String">

 

SELECT #{CUODE} ||#{DIE}|| #{I11TH} FROM DUAL

 

</selectKey>

 

MERGE INTO MY_TABLE SM
USING (SELECT #{id} SALES_NO
,#{AA} AA
,#{BB} BB
,#{CC} CC
FROM DUAL) MG
ON
......
....
..

</insert>

 

 

 
위 의 소스의 경우 id 값을 가지고 오지못하고 해당 값이 Not Null 이라면 오라클 익셉션이 발생합니다.
selectkey의 각 속성값을 살펴보면 다음과 같습니다.
 
Attribute Description
keyProperty The target property where the result of the 
selectKey statement should be set.
Can be a comma separated list of property names if multiple generated columns are expected.
keyColumn The column name(s) in the returned result set that match the properties.
Can be a comma separated list of column names if multiple generated columns are expected.
resultType The type of the result. MyBatis can usually figure this out, but it doesn't hurt to add it to be sure.
MyBatis allows any simple type to be used as the key, including Strings.
If you are expecting multiple generated columns, then you can use an Object that contains
the expected properties, or a Map.
order This can be set to BEFORE or AFTER.
If set to BEFORE, then it will select the key first, set the keyProperty and then execute
the insert statement. If set to AFTER, it runs the insert statement and
then the selectKey statement – which is common with databases like Oracle
that may have embedded sequence calls inside of insert statements.
statementType Same as above, MyBatis supports STATEMENTPREPARED and CALLABLE statement types
that map to StatementPreparedStatementand CallableStatement respectively
 
 
 
해당 문제를 해결하기 위해서 확인해야 할 것은 order 속성입니다. 
ORDER 속성은 BEFORE 와 AFTER를 선택할 수 있는데 해당 속성을 정의하지 않을경우 기본값이 AFTER입니다. 
BEFORE는 INSERT 문을 실행하기전 selectkey 구문을 수행하고 AFTER는 INSERT문을 수행한 후 selectkey가 수행됩니다. 
 
즉 올바른 동작을 위해서는 아래 예제와 같이 코드가 작성되어야 합니다. 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<insert id="queryId" parameterType="java.util.Map">
        <selectKey keyProperty="id" resultType="java.lang.String" order="BEFORE">
        SELECT #{ASDFAS} ||#{SDF}|| #{INVASDFONTH} FROM DUAL
        </selectKey>
        MERGE INTO MY_TABLE SM
        USING (SELECT #{id} SALES_NO
                     ,#{AA} AA
                     ,#{BB} BB
                     ,#{CC} CC
                 FROM DUAL) MG 
           ON
        ......
        ....
        ..
<insert>
cs

 

+ Recent posts