selectKey 사용이유, 방법

0

SQL

목록 보기
10/11

📌 사용 이유

  • SQL 수행작업 중 insert된 이후에 알 수 있는 값 또는, 생성된 값을 바로 가져와서 select 쿼리를 보내야 하는 경우가 있다.
  • 주로 생성하고 난 후의 인덱스(번호)를 가져와 작업해야 하는 상황에서 많이 사용한다.
    이런경우 java에서 insert 쿼리를 실행하고 값을 받은 후
    값을 가지고 다시 쿼리를 DB에 전송하는 방법이 있다.
  • 하지만, 불필요한 여러번의 DB 입출력은 시간이 느려진다는 단점이 있다.
    그때, selectKey를 사용하여 바로 적용할 수 있다.
    마이바티스, 아이바티스 두개 다 적용이 가능하다.
  • selectKey는 DB에 명령을 한번만 보내며, 우선 입력한 값의 결과값을 다음 쿼리로 바로 return 시켜주는 것이다.

📌 엘리먼트 속성

  • select key 엘리먼트 속성
  • keyProperty: selectKey구문의 결과가 셋팅될 대상 프로퍼티.
  • keyColumn: 리턴되는 결과셋의 칼럼명은 프로퍼티에 일치한다. 여러개의 칼럼을 사용한다면 칼럼명의 목록은 콤마를 사용해서 구분한다.
  • resultType: 결과의 타입. 마이바티스는 이 기능을 제거할 수 있지만 추가하는게 문제가 되지는 않을것이다. 마이바티스는 String을 포함하여 키로 사용될 수 있는 간단한 타입을 허용한다.
  • order: BEFORE 또는 AFTER를 셋팅할 수 있다. BEFORE로 설정하면 키를 먼저 조회하고 그 값을 keyProperty 에 셋팅한 뒤 insert 구문을 실행한다. AFTER로 설정하면 insert 구문을 실행한 뒤 selectKey 구문을 실행한다. 오라클과 같은 데이터베이스에서는 insert구문 내부에서 일관된 호출형태로 처리한다.
  • statementType: STATEMENT, PREPARED 또는 CALLABLE중 하나를 선택할 수 있다. 마이바티스에게 Statement, PreparedStatement 또는 CallableStatement를 사용하게 한다. 디폴트는 PREPARED 이다.

1. 자동 채번이 적용되지 않은 테이블에 id를 계산해서 삽입

<insert id="insertHobby" parameterType="hobby">
    /* order="BEFORE" 삽입 전에 조회 */
    /* selectKey 구문의 위치는 INSERT 쿼리 위, 아래 상관 없이 위치할 수 있습니다. */
    <selectKey keyProperty="hobbyId" resultType="int" order="BEFORE">
        SELECT MAX(hobby_id) + 1 FROM hobby
    </selectKey>

    /* #{hobbyId}에는 SelectKey 구문을 통해서 조회한 값이 저장되어 있습니다. */
    INSERT INTO hobby(hobbdy_id, hobby_name, user_id)
    VALUES (#{hobbyId}, #{hobbyName}, #{userId})
</insert>

2.자동 채번이 적용된 테이블에 삽입된 데이터를 다른 곳에서 바로 사용

<insert id="insertUser" parameterType="user">
    /* user 테이블은 AUTO_INCREMENT 설정이 되어 있습니다. */
    INSERT INTO user(user_name, column1, column2)
    VALUES (#{userName}, #{column1}, #{column2})

    /* order="AFTER" 삽입 후에 조회 */
    /* INSERT 구문이 실행된 후, 방금 넣은 데이터의 ID를 조회하면 자동으로 DTO 객체에 설정됩니다. */
    <selectKey keyProperty="userId" resultType="int" order="AFTER">
        SELECT LAST_INSERT_ID()
    </selectKey>
</insert>
<insert id="insertHobby" parameterType="hobby">
    INSERT INTO hobby(hobbdy_id, hobby_name, user_id)
    VALUES (#{hobbyId}, #{hobbyName}, #{userId})
</insert>


-> 여기서, LAST_INSERT_ID()는 가장 마지막에 INSERT 된 PK값으로,
<selectKey> 를 포함하고 있는 <insert id="insertUser"> </insert> 구문이 실행되고 난 후 (order= "AFTER") : insert가 진행 된 후의 PK값을 KeyProperty에 저장해라
그 insert된 직후의 (현재기준으로 pk의 Max값) pk값을 가져와서 keyProperty 인 userId 라는 변수로 가지고 있으라는 뜻이다.
나중에 selectKey로 선언해놓은 userId 값이 필요한 경우 #{} 안에 keyProperty로 선언해놓은 변수를 넣을 경우에 자동으로 값을 가져오게 된다.
-> 예시, 게시글을 저장한 후에 그 해당게시글에 파일도 저장할 것인데, 같은 PK를 공유할 것임.

<insert id="insertBoard" parameterType="map"> // 저장할 게시글
		INSERT INTO tb_board_test
		(
		title,
		content,
		user_id,
		user_name,
		created_date,
		modified_date
		) VALUES
		(
		#{title},
		#{content},
		#{userId},
		#{userName},
		NOW(),
		NOW()
		)
		<selectKey keyProperty="boardPKNum" resultType="int"
			order="AFTER"> 
			SELECT LAST_INSERT_ID()
		</selectKey>
  // 게시글을 저장한 후에(AFTER) 그 PK(ID)값을 keyProperty인 boardPKNum으로 저장한다.
	</insert>

출처

profile
백엔드를 공부하고 있습니다.

2개의 댓글

comment-user-thumbnail
2023년 6월 21일

감사합니다. 셀렉트키 이해하는데 도움이 많이 되었네요 ㅎㅎ

1개의 답글

관련 채용 정보