-동적(Dynamic)으로 변화되어야하는 SQL 쿼리를 작성할 수 있도록 도와주는 마이바티스 태그
-실행 시 조건에 따라 where절이 바뀌어 실행되는 쿼리문
-컴파일 시 SQL문을 확정할 수 없는 경우 사용
-select, insert, update, delete 안에서 사용한다.
-if, choose, trim, foreach 태그를 제공한다.
<choose>
<when test="조건문1">
</when>
<when test="조건문2">
</when>
<otherwise>
</otherwise>
</choose>
- prefix : 접두어 지정
- prefixOverrides : 접두어로 설정한 값과 겹쳐지면 제거할 항목을 지정
- suffix : 접미어 설정
- suffixOverrides : 접미어로 설정한 값과 겹쳐지면 제거할 항목을 지정
- 동적쿼리 사용시 WHERE 1=1 (and, or처리하기위한 식) 위험성 : 파라미터가 모두 null로 전달이 된다면 해당 쿼리들은 모두 전체 조회가 됨, 데이터 양에 따라 어플리케이션 응답 지연 문제 등이 발생 가능
- where태그(trim태그)를 사용하면 where 1=1은 사용하지 않을 수 있다. but, 파라미터를 세팅하지 못하고 모두 null로 넘어오게 된다면 where 1=1과 동일하게 전체 조회 쿼리가 된다.
- 예방법 : trim 태그를 사용할 때 where는 직접 작성하고(prefix="where"사용x), prefixOverrides에 and만 작성하여 사용
SELECT * FROM TBL_BOARD
<where>
<if test="bno != null">]
BNO = #{bno}
</if>
<trim prefixOverrides="AND">
AND ROWNUm = 1
</trim>
</where>
<c:set var = "testStr" value = "test string"/>
<c:if test = "${fn:contains(testStr, 'test')}">
<span>문자열 포함</span>
</c:if>
<c:if test = "${fn:contains(testStr, 'hello')}">
<span>문자열 미포함</span>
</c:if>
<select id="getStoreInfo" resultMap="mainMap">
SELECT si.*
FROM store_info si
LEFT JOIN store_menu sm ON sm.store_id = si.store_id
WHERE
<trim prefixOverrides="AND|OR">
<if test="params.keyword != null and params.keyword != ''">
<choose>
<when test="params.searchType == 'menu_name'">
AND si.store_name LIKE '%' || #{params.keyword} || '%'
</when>
<when test="params.searchType == 'menu_category'">
AND si.store_category LIKE '%' || #{params.keyword} || '%'
</when>
<otherwise>
AND (si.store_name LIKE '%' || #{params.keyword} || '%'
OR si.store_category LIKE '%' || #{params.keyword} || '%')
</otherwise>
</choose>
</if>
<if test="params.category != null and params.category != ''">
AND store_category LIKE '%' || #{params.category} ||'%'
</if>
</trim>
</select>
<c:if test="${not empty store.store_category}">
<span>카테고리 :
<c:set var="seenCategories" value="" />
<!-- 특정 카테고리로 검색 시 -->
<c:forEach var="category" items="${fn:split(store.store_category, '/')}">
<c:if test="${fn:contains(category, param.keyword)}">
<c:if test="${not fn:contains(seenCategories, category)}">
<c:if test="${!empty seenCategories}">
/
</c:if>
${category}
<c:set var="seenCategories" value="${seenCategories}${category}/" />
</c:if>
</c:if>
</c:forEach>
<!-- "ALL" 또는 메뉴 이름으로 검색 시 모든 카테고리 출력 -->
<c:if test="${param.searchType == 'menu_name' || param.searchType == 'all' || param.searchType == null}">
<c:forEach var="category" items="${fn:split(store.store_category, '/')}">
<c:if test="${not fn:contains(seenCategories, category)}">
<c:if test="${!empty seenCategories}">
/
</c:if>
${category}
<c:set var="seenCategories" value="${seenCategories}${category}/" />
</c:if>
</c:forEach>
</c:if>
</span><br>
</c:if>