[Spring] mybatis의 selectKey를 통한 시퀀스 획득

류넹·2024년 3월 8일
1

Spring

목록 보기
29/50

📌 <selectKey> 태그

* 해당 내용은 Oracle 기준이며, 데이터베이스마다 약간의 차이가 있음

  • <insert> 태그 내부에 정의하는 태그
  • INSERT 구문 실행 전, 실행 후 실행할 SQL문을 지정할 수 있다.
  • <selectKey> 태그에서 실행하는 SQL 구문은 새로 발행되는 기본키값을 획득하는 쿼리

<selectKey> 사용 목적

  • FK 컬럼이 있는 테이블과, 참조의 대상이 되는 테이블을 한꺼번에 Insert해야 하는 상황에 사용한다.
  • 예를 들어, 주문이 발생했을 때 주문 테이블과 결제 테이블의 Insert 작업은 동시에 진행되어야 한다.
    이 때, selectKey를 사용한다.



<selectKey>의 주요 속성

1. keyProperty

  • <selectKey> 태그의 SQL 구문 실행 결과가 대입될 대상 프로퍼티명(멤버변수명)

2. resultType

  • <selectKey> 태그의 SQL 구문 실행 결과로 획득되는 값의 타입을 지정

3.order

  • <selectKey> 태그에 정의된 SQL 구문의 실행 시점을 지정
  • order="BEFORE"와 order="AFTER" 중 하나를 설정




🚩 예시)

  • Oracle에서 <selectKey>를 사용하는 방법은 2가지가 있다.
    아래 방법이 1번째 방법이고, 2번째 방법은 더 아래의 Oracle과 mysql 비교 부분 참고 ("BEFORE"/"AFTER" 등이 다름)
<insert id="insertUser" parameterType="com.example.vo.User">
    <selectKey keyProperty="no" resultType="int" order="BEFORE">
        select
        users_seq.nextval
        from
        dual
    </selectKey>
    insert into shop_users
    (user_no, user_id, user_password, user_name, user_email, user_tel, user_birth)
    values
    (#{no}, #{id}, #{password}, #{name}, #{email}, #{tel}, #{birth})
</insert>
  1. selectKey를 통해 insert문 실행 전에 시퀀스 조회해서 증가된 시퀀스 번호를 획득하고,

  2. 파라미터타입에 명시되어 있는 객체(vo.User)의 프로퍼티를 keyProperty="no"으로 받아와서 int 타입으로 반환

  3. ==> insert문에서 #{no}로 사용 가능


참고 이미지)




💡 Oracle과 mysql 비교

mysql은 애초에 시퀀스가 없기 때문에 insert구문에 no를 적지도 않음.
❓ 그럼 어떻게 no를 생성하냐?
다른 컬럼들만 가지고 insert를 하면 자동으로 no가 획득됨.

따라서, mysql은 <selectKey>를 작성하는 방법이 조금 다름

1. Oracle

<!--oracle -->         
<insert id="insertSelectSeq" parameterType="com.model.Test">
    INSERT INTO seq_test(idx,title)
         VALUES(idx_test_seq.nextval,#{title})
    <selectKey keyProperty="idx" resultType="Integer" order="AFTER">
        SELECT idx_test_seq.currval FROM dual
    </selectKey>
</insert>

2. mysql

mysql의 last_insert_id 함수는 테이블의 마지막 auto_increment 값을 리턴한다.

<!--mysql-->
<insert id="insertSelectSeq" parameterType="com.model.Test">
    INSERT INTO seq_test(title)
         VALUES(#{title})
    <selectKey keyProperty="idx" resultType="Integer" order="AFTER">
        SELECT LAST_INSERT_ID()
    </selectKey>
</insert>



* 데이터베이스 종류 참고
Oracle - Oracle
mysql - Oracle
mssql Server - MS





References

profile
학습용 커스터마이징 간단 개발자 사전

0개의 댓글