반응형
# 목적
- mybatis의 동적 쿼리 정리
🔎 mybatis의 동적 쿼리
- mybatis는
<if>
,<choose> ~ <when> ~ <otherwise>
,<where>
,<set>
,<foreach>
태그를 사용해서 동적 SQL을 작성할 수 있다. - mybatis에서 동적 SQL 작성을 지원하기 위해서 제공하는 태그는 JSTL의 태그와 사용법이 매우 비슷하다.
1. <if>
태그
- 형식
<if test="조건식">
SQL 구문
</if>
<!--
* 제시된 조건식은 true/false로 판정되는 조건식이다.
* 제시된 조건식이 true로 판정되면 태그 내부의 SQL 구문이 사용된다.
-->
- 예시
- 매퍼 인터페이스의 추상메서드
List<Book> getBooks(Criteria criteria)
- 매퍼 파일
<select id="getBooks" parameterType="dto.Criteria" resultType="vo.Book">
select
*
from
books
where
book_status = 'SELL'
<if test="title != null">
book+title = #{title}
</if>
</select>
2. <choose> ~ <when> ~ <otherwise>
- 형식
<choose>
<when test="조건식1">
SQL 구문1
</when>
<when test="조건식2">
SQL 구문2
</when>
<when test="조건식3">
SQL 구문3
</when>
<otherwise>
SQL 구문4
</otherwise>
</choose>
<!--
* 제시된 여러 조건 중에서 조건식이 true로 판정되는 SQL 구문이 사용되고,
제시된 모든 조건식이 false로 판정되면 otherwise의 SQL 구문이 사용된다.
* <otherwise>는 생략 가능
-->
- 예시
<select id="getBooks" parameterType="dto.Criteria" resultType="vo.Book">
select
*
from
books
where
book_status = 'SELL'
<choose>
<when test="title != null">
and book_title = #{title}
</when>
<when test="author != null">
and book_author = #{author}
</when>
<when test="publisher != null">
and book_publisher = #{publisher}
</when>
</choose>
</select>
3. <where>
- 형식
<where>
<!-- 동적 SQL 구문 -->
<if test="조건식">
SQL 구문
</if>
</where>
<!--
* <where> 태그는 반드시 <if>, <choose> ~ <when> ~ <otherwise>, <foreach> 태그를
사용하는 동적 SQL 구문이 위치해야 한다.
* <where> 태그는 2가지 동작을 처리한다.
1. where 키워드 추가
ex)
<select>
select
*
from
books
where
book_status = 'SELL'
<if test="title != null">
and book_title = #{title}
</if>
</select>
=====> 1) 위 경우에는 <where>태그를 사용할 필요가 없다.
<select>
select
*
from
books
where
<if test="title != null">
and book_title = #{title}
</if>
</select>
=====> 2) 위 경우에 title 값이 null이면 실행되는 SQL은 아래와 같다.
select
*
from
books
where
=====> 3) 위의 SQL은 where절이 비어있어서 오류가 발생하기 때문에
아래와 같이 <where> 태그를 이용해서 작성해야 한다.
<select>
select
*
from
books
<where>
<if test="title != null">
and book_title = #{title}
</if>
</where>
</select>
2. and 키워드 제거
ex)
<select>
select
*
from
books
where
<if test="title != null">
and book_title = #{title}
</if>
<if test="author != null">
and book_author = #{author}
</if>
<if test="publisher != null">
and book_publisher = #{publisher}
</if>
</select>
=====> 위 경우에 title이 null이고 author나 publisher가 null이 아니면
아래와 같은 SQL 구문이 실행되고, where 다음에 and가 있어서 오류가 발생한다.
select
*
from
books
where
and book_author = ?
=====> 아래처럼 <where> 태그를 사용하면 and가 자동으로 제거된다.
select
*
from
books
<where>
and book_author = #{author}
</where>
-->
4. <set>
- 형식
<set>
동적 SQL 구문
</set>
<!--
* <set> 태그는 동적으로 SET 키워드를 추가하고, 필요없는 콤마(,)를 제거한다.
-->
- 예시
<update>
update books
set
<if test="title != null">
book_title = #{title},
</if>
<if test="price != 0">
book_price = #{price},
</if>
<if test="filename != null">
book_filename = #{filename},
</if>
where
book_no = #{no}
</update>
<!--
1) 위의 경우 title, price에는 값이 있고, filename에 값이 null 이면
아래와 같은 SQL 구문이 실행되고, 맨 마지막에 ','가 있어서 오류가 발생한다.
update books
set
book_title = #{title},
book_price = #{price},
where
book_no = #{no}
-->
<update>
update books
<set>
<if test="title != null">
book_title = #{title},
</if>
<if test="price != 0">
book_price = #{price},
</if>
<if test="filename != null">
book_filename = #{filename},
</if>
</set>
where
book_no = #{no}
</update>
<!--
2) 위의 경우 title, price에는 값이 있고, filename에 값이 null 이면
아래와 같은 SQL 구문이 실행되고, 맨 마지막에 위치한 ','가 제거된다.
update books
set
book_title = #{title},
book_price = #{price}
where
book_no = #{no}
-->
5. <foreach>
- 형식
<foreach item="num" index="index" collection="productNumbers"
open="(" separator="," close=")">
#{num}
</foreach>
<!--
* 콜렉션에 대한 반복처리를 지원하는 태그
* in 연산자와 주로 사용된다.
-->
- 주요 속성
- item
- collection에서 지정된 배열 혹은 List에서 순서대로 하나씩 추출되는 값을 담을 변수명을 지정한다.
- index
- collection에서 지정된 배열 혹은 List를 반복처리할 때마다 0부터 시작하는 인덱스 값을 담을 변수명을 지정한다.
정의만 하고 sql 구문에서는 사용하지 않는다.
- collection에서 지정된 배열 혹은 List를 반복처리할 때마다 0부터 시작하는 인덱스 값을 담을 변수명을 지정한다.
- collection
- 반복대상이 되는 값을 담고 있는 프로퍼티명 혹은 파라미터명을 지정한다.
- open
<foreach>
태그로 반복을 시작하기 전에 sql 구문에 출력할 컨텐츠를 지정한다.
- close
<foreach>
태그로 반복이 종료되었을 때 sql 구문에 출력할 컨텐츠를 지정한다.
- separator
- #{num}으로 값을 하나씩 출력할 때마다 각각의 값을 구분하는 구분문자를 지정한다.
- 예시
- 매퍼 인터페이스의 추상메서드
public interface BookMapper {
void deleteBooks(@Param("bookNumbers") List<Integer> bookNumbers);
}
- 매퍼 파일
<delete>
delete from books
where
book_no in
<foreach index="index" item="value" collection="bookNumbers"
open="(" separator="," close=")">
#{value}
</foreach>
</delete>
<!--
* bookNumbers로 찾은 값 : List<Integer>, 정수값을 여러개 담고 있는 List 객체를 전달받는다.
* 위의 SQL 구문이 실행되면 아래와 같은 SQL이 실행된다.
delete from books
where
book_no in
(100, 102, 104)
-->
- 참고 이미지

< 해당 글은 velog에서 이전하며 옮겨온 글로, 가독성이 좋지 않을 수 있는 점 양해 부탁드립니다. >
🔗 velog 버전 보기 : https://velog.io/@ryuneng2/Spring-mybatis의-동적쿼리
'BackEnd > Spring' 카테고리의 다른 글
[Spring] 게시판 리스트의 모든 데이터 조회 기본 순서 정리 (1) | 2025.01.17 |
---|---|
[Spring] mybatis 쿼리 캐싱 (<cache> 태그) (0) | 2025.01.17 |
[Spring] Spring MVC의 주요 컴포넌트(Model, View 전달 과정) (0) | 2025.01.17 |
[Spring] 코드 작성 순서 (0) | 2025.01.17 |
[Spring] 스프링의 주요 어노테이션과 요청핸들러 메서드 (0) | 2025.01.17 |