본문 바로가기

삽질

Mybatis selectKey 사용 방법

1. selectKey란?

Mybatis는 DB에서 특정 값을 가져와서 쓸 수 있도록 selectKey 기능을 제공합니다.

보통 id 값을 auto-increment 해서 사용합니다.

selectKey를 이용하면, 이 id 값을 바로 가져와서 쓸 수 있습니다.

 

밑에서 제가 사용할 도메인 코드는 다음과 같습니다.

public class City {
	private int id;
	private String name;
	private String countryCode;
	private String district;
	private int population;
	
	// getter, setter 생략
}

 

2. selectKey 사용 방법

selecKey는 크게 after, before 방법으로 나눌 수 있습니다.

 

2.1 selectKey - after 사용 방법

selectKey를 사용하는 방법은 아래와 같이 태그 내부에 적으면 됩니다.

아래는 데이터를 삽입하고 난 이후에 id 값을 가져오는 방법입니다.

<insert id="insertCity" parameterType="city" >
	<!-- 태그 sql문 -->
	insert into city(name, CountryCode, District, Population)
	values(#{name}, #{countryCode}, #{district}, #{population})	

	<selectKey order="AFTER" resultType="int" keyProperty="id">
	  <!-- (selectKey) 내부 sql문 -->
		select last_insert_id()
	</selectKey>
</insert>

설명

  • order=”AFTER” : 태그 sql문(insert)이 동작하고 나서 selectKey가 동작하도록 합니다.
  • resultType=”int” : 내부 sql문의 반환 값이 int 인 것을 의미합니다.
  • keyProperty="id" : 반환 값이 setter를 통해서 id에 매핑 될 것을 의미합니다.<aside> 💡 setter를 통해서 주입되므로, setId()가 필요합니다!!
  • </aside>
  • public class City { private int id; // <- id에 반환 값이 들어가는 것입니다. ... }

위에서 auto-incremente된 id 값을 가져올 수 있다고 언급했습니다.

그 방법이 이 방법 인 것입니다.

내부 sql문의 **select last_insert_id()**를 통해 마지막에 insert 된 데이터를 얻을 수 있습니다.

public String insert() {
	City city = new City(-1, "뉴도시", "KOR", "ㅇㅇ", 1000);
	worldMapper.insertCity(city);
	System.out.println("등록된 도시 정보의 ID : "+city.getId()); // 15 출력	
}

따로 쿼리를 날리지 않더라도 마지막에 삽입된 id 를 가져올 수 있습니다.

 

2.2 selectKey - before 사용 방법

아래는 마지막에 삽입된 데이터를 수정하는 방법입니다.

<update id="updateLastCity" parameterType="city">
	<!-- 태그 sql -->
	update city
	set name=#{name}, CountryCode=#{countryCode}, district=#{district}, population=#{population}
	where id = #{id}

	<selectKey order="BEFORE" resultType="int" keyProperty="id">
		<!-- (selectKey) 내부 sql -->
		select max(id) from city
	</selectKey>
</update>

단지 order이 BEFORE로만 바뀌었고, 전체적인 방법은 동일합니다.

 

여기서 눈 여겨 볼 점이 있습니다.

왜 여기서는

select last_insert_id()를 사용하지 않는 것일까요?

 

자세히 설명하기에는 복잡한 내용이지만,

last_insert_id()는 DB 내부 Session에 저장된 값을 사용하기 때문입니다.

 

order=”AFTER”는 auto-increment로 증가된 id 값이 Session에 저장되어있기 때문에 가져올 수 있는 것입니다.

order="BEFORE"는 새로운 Session에서 동작되기 때문에 값을 가져올 수 없습니다.

'삽질' 카테고리의 다른 글

클라우드 네이티브란?  (0) 2023.11.27
REST API와 HTTP Header  (0) 2023.10.31
Spring Web의 두 가지 기본 Context  (0) 2023.10.22
Spring Web MVC 동작 과정  (0) 2023.10.21
findAll과 findById 조회의 차이  (0) 2023.10.12