Post

[MyBatis] 동적쿼리 정리



MyBatis logo




MyBatis 동적쿼리란?

실행 시점의 조건에 따라 SQL문을 동적으로 생성할 수 있도록 MyBatis에서 제공하는 기능으로, 유연한 쿼리 작성을 돕는다.


<if>

특정 조건에 따라 SQL문을 포함하거나 제외한다. 참인 조건이 모두 실행된다.

1
2
3
4
5
6
7
8
9
10
11
<select id="findUsers" parameterType="userDto" resultType="User">
     SELECT *
     FROM USER
     WHERE 1=1
     <if test= 'name != null and name !=""'>
          AND NAME = #{name}
     </if>
     <if test= 'age != null and age !=""'>
          AND AGE = #{age}
     </if>
</select>

<choose>, <when>, <otherwise>

Switch문처럼 여러 조건 중 하나를 선택한다.
참인 조건이 나오면 그 조건만 실행하고 종료된다는 점에서 if문과 다르다.
3개의 태그가 한 세트이므로 하나의 태그라도 빠지면 오류난다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<select id="findUsers" parameterType="userDto" resultType="User">
     SELECT *
     FROM USER
     WHERE 1=1
     <choose>
          <when test='name != null and name !=""'>
               AND NAME = #{name}
          </when>
          <when test='age != null and age !=""'>
               AND AGE = #{age}
          </when>
          <otherwise>
               AND STATUS = 'active'
          </otherwise>
     </choose>
</select>

<where>

조건에 따라 where절을 자동으로 추가하며, 첫 번째 조건 앞의 불필요한 AND/OR를 자동 제거해준다.

1
2
3
4
5
6
7
8
9
10
11
12
<select id="findUsers" parameterType="userDto" resultType="User">
     SELECT *
     FROM USER
     <where>
          <if test='name != null and name !=""'>
               AND NAME = #{name} 
          </if>
          <if test='age != null and age !=""'>
               AND AGE = #{age}
          </if>
     </where>
</select>

첫 번째 조건만 충족 시 실행 쿼리

1
2
3
SELECT *
FROM USER
WHERE NAME = #{name}

두 번째 조건만 충족 시 실행 쿼리

1
2
3
SELECT *
FROM USER
WHERE AGE = #{age}

모두 충족 시 실행 쿼리

1
2
3
4
SELECT *
FROM USER
WHERE NAME = #{name}
AND   AGE = #{age}

<trim>

where절이나 SQL의 특정 부분에서 접두어(prefix)나 접미어(suffix)를 제어한다.

  • prefix : 쿼리문이 시작될 때, 삽입할 문자열이다.
  • suffix : 쿼리문이 종료될 때, 삽입할 문자열이다.
  • prefixOverids : 실행될 퀴리문 맨 앞단의 단어가 설정값과 동일하다면 해당 문자를 지운다.
  • suffixOverids : 실행될 퀴리문 맨 뒷단의 단어가 설정값과 동일하다면 해당 문자를 지운다.
1
2
3
4
5
6
7
8
9
10
SELECT *
FROM USER
<trim prefix="WHERE" prefixOverrides="AND | OR">
          <if test='name != null and name != ""'>
               NAME = #{name} 
          </if>
          <if test='age != null and age != ""'>
               AGE = #{age}
          </if>
</trim>

<foreach>

배열이나 컬렉션 데이터를 반복적으로 처리한다.

  • collection : 전달받은 인자, List 또는 Array만 가능하다.
  • item : 전달받은 인자 값을 alias명으로 대체한다.
  • open : 쿼리문이 시작될 때, 삽입할 문자열이다.
  • close : 쿼리문이 종료될 때, 삽입할 문자열이다.
  • separaator : 반복 사이에 출력할 문자열이다.
  • index : 반복되는 구문 번호이다. 0부터 순차적으로 증가한다.
1
2
3
4
5
6
SELECT *
FROM USER
WHERE NAME IN
<foreach collection="nameList" item="name" open="(" separator="," close=")">
          #{name} 
</foreach>

nameList=[“홍길동”, “심청이”, “갑을병”] 일 때, 아래와 같이 실행된다.

1
2
3
SELECT *
FROM USER
WHERE NAME IN ('홍길동', '심청이', '갑을병')

<set>

UPDATE문에서 동적으로 컬럼을 설정하며, 불필요한 쉼표(,)를 제거한다.

1
2
3
4
5
6
7
8
9
10
11
12
<update id="updateUser" parameterType="userDto">
     UPDATE user
     <set>
          <if test='name != null and name != ""'>
               NAME = #{name},
          </if>
          <if test='age != null and age != ""'>
               AGE = #{age},
          </if>
     </set>
     WHERE ID = #{id}
</update>

CDATA로 묶으면 동적쿼리 작동 안하니 주의!


This post is licensed under CC BY 4.0 by the author.