mybatis는 <if>
, <choose> ~ <when> ~ <otherwise>
, <where>
, <set>
, <foreach>
태그를 사용해서 동적 SQL을 작성할 수 있다.
mybatis에서 동적 SQL 작성을 지원하기 위해서 제공하는 태그는 JSTL의 태그와 사용법이 매우 비슷하다.
<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>
<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>
<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>
-->
<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}
-->
<foreach>
<foreach item="num" index="index" collection="productNumbers"
open="(" separator="," close=")">
#{num}
</foreach>
<!--
* 콜렉션에 대한 반복처리를 지원하는 태그
* in 연산자와 주로 사용된다.
-->
<foreach>
태그로 반복을 시작하기 전에 sql 구문에 출력할 컨텐츠를 지정한다.<foreach>
태그로 반복이 종료되었을 때 sql 구문에 출력할 컨텐츠를 지정한다.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)
-->