본문 바로가기
Category/Database

[Mybatis] 동적 SQL 사용법

by developer__Y 2024. 5. 7.

Mybatis를 통해 동적 SQL문을 작성하는 구문은 크게 4가지가 있다.

- if

- choose (when,otherwise)

- trim

- foreach

 

*공식문서의 예문 참고

if 구문

가장 빈번하게 사용되는 if구문은 보통 where절에서 사용된다.

 

<select id="findActiveBlogWithTitleLike"
     resultType="Blog">
  SELECT * FROM BLOG
  WHERE state = ‘ACTIVE’
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>

 

위 구문은 BLOG TABLE의 모든 컬럼을 조회할때 where 조건이 state = 'ACTIVE' 이고,

<if> 단일조건문을 통해 'title'값이 null이 아닌경우(isnotnull)에는 AND title LIKE #{title} 조건을 활성화한다.

또한 별개의 또다른 단일 조건문을 통해 'author'가 not null 이면서 author.name이 not null일때

AND author_name LIKE #{author.name} 조건을 활성화한다.

즉, 두개의 <if>조건이 모두 false일 경우 SELECT * FROM BLOG WHERE state = 'ACTIVE'; 구문이 실행된다.

 

Choose When Otherwise

 

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

 

Java의 Switch 문법과 유사한 choose구문은 여러개의 조건중 해당하는 조건의 구문이 활성화된다.

<choose> 태그내의 <when> 태그를 통해 각각의 조건을 명시하며, <when>의 조건을 만족시키는 절이 없을경우

<otherwise> 조건절이 활성화 된다.

 

<where>와 where 1=1

 

실무에서 SQL문에 where 1=1을 자주 사용하는 것을 볼수있다.

아래의 쿼리문을 참고하면 왜 where 1=1을 사용하는지 알수있다.

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG
  WHERE
  <if test="state != null">
    state = #{state}
  </if>
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>

 

<WHERE 1=1>

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG
  WHERE 1=1
  <if test="state != null">
   AND state = #{state}
  </if>
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>

 

만약 위의 구문에서 <if test="state !=null> 조건이 false이고, <if test="title != null">이 true이면 

SQL구문은 

SELECT * FROM BLOG AND title LIKE #{title}으로 실행시 오류가 발생한다.

따라서 where 1=1 을 기본 SQL구문에 넣고, 조건절을 만족시 AND ~이후의 구문을 넣어주면

조건절의 존재 여부와 상관없이 where 조건을 손쉽게 추가할수있으며 이후에 추가로 AND ~ 조건을 추가하며 유지보수성을 높일수있다.

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG
  <where>
    <if test="state != null">
         state = #{state}
    </if>
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>

 

이러한 기능을 Mybatis에서 <where> 태그를 통해 사용할수도 있다.

<where>태그는 만족하는 조건절이 있을경우 where 구문을 추가하며, SQL 구문이 AND나 OR으로 시작한다면 지워버린다.

 

Foreach

 

동적 SQL을 사용하면서 Collection에 대한 반복적인 처리를 사용할때 foreach 구문을 통해 처리할수있다.

<foreach> 태그 내부에서 사용할수있는 item, index변수를 통해 반복가능한 배열을 지정할수있다.

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  <where>
    <foreach item="item" index="index" collection="list"
        open="ID in (" separator="," close=")" nullable="true">
          #{item}
    </foreach>
  </where>
</select>

 

 

open , close 요소를 사용하여 list 컬렉션을 반복하면서, 해당하는 #{item}을 ID in ( #{item1},#{item2},...) 식으로 동적으로 SQL구문을 작성할 수 있다.