Dynamic SQL
- 검색조건에 따라 검색해야 하는 SQL문이 달라지기 때문에 이를 처리하기 위해서 사용
- MyBatis의 표현식
- if
- trim(where, set)
- choose(when, otherwise)
- foreach
- Dynamic SQL 작성 시 유의사항
- MyBatis 구문을 이용하여 SQL문이 실행 시에 변경되기 때문에 모든 케이스에 대한 테스트가 이루어져야 함.
- 동적 SQL문이 없는 상태에서 정상적인 실행을 확인 후, 동적 SQL을 추가해서 개발해야 함.
if
- MyBatis에서 가장 공통적으로 사용되는 요소
<select id="findActiveBlogWithTitleLike" resultType="Blog">
SELECT * FROM BLOG WHERE STATE='ACTIVE'
<if test="title!=null">
AND title like #{title}
</if>
</select>
- 위 구문은 author와 author.name 파라미터에 값이 존재할 경우
AND author_name like ${author.name} 구문을 본 쿼리문에 포함시킨다.
- 파라미터 타입 안에 다른 타입(클래스)가 포함되어 캡슐화를 이룰 경우 .(dot) 연산자로 접근할 수 있다.
choose(when, otherwise)
<select id="findActiveBlogWithTitleLike" 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>
- title 파라미터 값이 존재하면 AND title like #{title} 구문을 포함
- author와 author.name 파라미터 값이 존재한다면 AND author_name like #{author.name} 구문을 포함
- 둘다 존재하지 않는다면 AND featured=1 구문을 포함
trim(where, set)
<select id="findActiveBlogWithTitleLike" 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>
- 위 구문은 잘못 사용된 예
- 만약 아무런 파라미터도 없다면 아래와 같은 쿼리가 만들어짐
SELECT *
FROM BLOG
WHERE
<select id="findActiveBlogWithTitleLike" 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>
- 만약 where 다음 AND 혹은 OR가 바로 올 경우는 오류가 발생하기 때문에 trim을 사용해 AND, OR를 삭제시킬 수 있다.
- prefix가 where이면 if문이 하나라도 참인 경우에는 where가 붙어서 진행되게 됨.
- 두 개 이상이 참이면 where은 붙지 않고 AND만 붙어서 작성된다.
<select id="findActiveBlogWithTitleLike" resultType="Blog">
SELECT *
FROM BLOG
<trim prefix="WHERE" prefixOverrids="AND">
<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>
</trim>
</select>
foreach
- Dynamic 쿼리에서 공통적으로 필요한 기능은 Collection의 반복 처리 기능
- IN 키워드를 사용할 때 종종 사용됨
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT * FROM POST P WHERE ID in
<foreach item="item" index="index" collection="list"
open="("separator=","close=")">
#{item}
</foreach>
</select>
- collection 속성은 List일 경우는 list, array가 사용됨