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 |