가희의자기개발블로그
동적SQL 본문
동적 SQL엘리먼트들을 JSTL이나 XML기반의 텍스트 프로세서를 사용해 본 사람에게는 친숙할 것이다. 마이바티스의 이전 버전에서는 알고 이해해야 할 엘리먼트가 많았다. 마이바티스의 다른 엘리먼트의 사용을 최대한 제거하기 위해 OGNL기반의 표현식을 가져왔다.
01_ IF
동적 SQL에서 가장 공통적으로 사용되는 것으로 where의 일부로 포함될 수 있다.
<select id="findActiveBlogWithTitleLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
</select>
이 구문은 선택적으로 문자열 검색 기능을 제공할 것이다. 만약에 title값이 없다면 모든 active 상태의 Blog가 리턴될 것이다. 하지만 title 값이 있다면 그 값과 비슷한 데이터를 찾게 될 것이다.
title과 author를 사용하여 검색하고 싶다면?
<select id="findActiveBlogLike"
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>
02_ trim, where, set
앞서 예제는 악명높게 다양한 엘리먼트가 사용된 동적 sql이다. "if" 예제를 사용해보자
<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>
어떤 조건에도 해당하지 않는다면 어떤 일이 벌어질까? 아마도 다음과 같은 sql이 만들어질 것이다.
SELECT * FROM BLOG
WHERE
아마도 이건 실패할 것이다. 두번째 조건에만 해당된다면 무슨 일이 벌어질까> 아마도 다음과 같은 sql이 만들어질 것이다.
SELECT * FROM BLOG
WHERE
AND title like ‘someTitle’
이것도 아마 실패할 것이다. 실패하지 않기 위해서는 수정해야 한다.
<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>
where엘리먼트는 태그에 의해 컨텐츠가 리턴되면 단순히 "where"만을 추가한다. 게다가 컨텐츠가 "and"나 "or"로 시작한다면 그 "and"나 "or"를 지워버린다.
만약에 where 엘리먼트가 기대한 것처럼 작동하지 않는다면 trim엘리먼트를 사용자 정의할 수도 있다. 예를들어 다음은 where엘리먼트에 대한 trim기능과 동일하다.
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
override 속성은 오버라이드하는 텍스트의 목록을 제한한다. 결과는 override속성에 명시된 것들을 지우고 with속성에 명시된 것을 추가한다.
다음 예제는 동적인 update구문의 유사한 경우이다. set엘리먼트는 update하고자 하는 칼럼을 동적으로 포함시키기 위해 사용될 수 있다.
<update id="updateAuthorIfNecessary">
update Author
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
<if test="bio != null">bio=#{bio}</if>
</set>
where id=#{id}
</update>
여기서 set 엘리먼트는 동적으로 set키워드를 붙히고 필요없는 콤마를 제거한다.
trim 엘리먼트로 처리하면 아래와 같다.
<trim prefix="SET" suffixOverrides=",">
...
</trim>
03_ foreach
동적 sql 에서 공통적으로 필요한 것은 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>
foreach엘리먼트는 collection을 명시하는 것을 허용한다. 엘리먼트 내부에서 사용할 수 있는 item, index두가지 변수를 선언한다. 이 엘리먼트는 또한 열고 닫는 문자열로 명시할 수 있고 반복간에 둘 수 있는 구분자도 추가할 수 있다.
※컬렉션 파라미터로 map이나 배열객체와 더불어 list나 set등과 같은 반복가능한 객체를 전달 할 수 있다. 반복가능하거나 배열을 사용할때 index값은 현재 몇번째 반복인지를 나타내고 value항목은 반복과정에서 가져오는 요소를 나타낸다.
04_ bind
bind엘리먼트는 OGNL표현을 사용해서 변수를 만든 뒤 컨텍스트에 바인딩한다.
<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>
'백엔드 > myBatis' 카테고리의 다른 글
자바 API (0) | 2020.07.06 |
---|---|
Mapper XML파일 (0) | 2020.07.04 |
매퍼 설정 (0) | 2020.07.01 |
myBatis 시작하기 (0) | 2020.06.30 |
myBatis 개념 (0) | 2020.06.22 |