필터링 기능 구현 시 다중 값을 쿼리하거나 특정 값 선택 여부에 따라 동적 쿼리로 구현해야 하는 경우,
우선 MyBatis 에 넘길 객체의 요소를 아래와 같이 설정한다.
@Data
@Alias("clothes")
public class ClothesDTO {
private String keyword;
private String brand;
private List<String> type;
private int minCost;
private int maxCost;
}
keyword 는 사용자가 입력한 검색어, brand 는 단일 선택 값, type 은 체크박스 다중 선택값을 List 에 담아 전달한다.
minCost, maxCost 는 검색하고자 하는 특정 값의 범위를 지정한다.
MyBatis 에는 다양한 동적쿼리문이 있는데 대표적으로 if 문과 foreach 문이 있고 이는 JSTL 문과 유사한 면이 있다.
먼저 if 문의 기본적인 구문은 아래와 같다.
<if test='param != null'>
{query syntax}
</if>
test 에 지정된 조건문(!=, ==, <, >, equals() ... ) 에 따라 내부의 쿼리문이 작성될 지 여부를 결정한다.
아래는 다중 값을 쿼리하기 위한 foreach 문
<foreach item="item" index="index" collection="paramList" open="(" separator="," close=")">
#{item}
</foreach>
리스트의 특정 인덱스를 지정하기 위해서 index 변수를 사용 가능하고,
open, close, separator 는 리스트가 괄호로 열고 닫히고 쉼표를 기준으로 요소를 구분한다는 의미를 가지고 있다.
item, collection 은 foreach 문에 대입해보면 아래와 같다.
for (String item : paramList) {
System.out.println(item);
}
이렇게 List 의 값을 하나씩 꺼내 각각 쿼리문에 적용한다.
이런 방식으로 필터링할 값을 저장한 ClothesDTO 객체를 매개변수로 전달해 아래와 같이 쿼리문을 작성할 수 있다.
<select id="getList" parameterType="clothes" resultType="clothes">
select * from clothes where brand = #{brand}
<if test='keyword != null and !keyword.equals("")'>
and name like '%' || #{keyword} || '%'
</if>
<if test='type.size != 0'>
and type in
<foreach item="var" index="idx" collection="type" open="(" separator="," close=")">
#{var}
</foreach>
</if>
<![CDATA[
and min_cost >= #{minCost} and max_cost <= #{maxCost}
]]>
</select>
keyword 에 값이 null 값이 아니고 공백이 아닐 시 내부 like 쿼리문이 작성되고,
다중 선택값이 저장된 리스트의 크기가 0보다 클 경우, 즉 값이 존재할 경우 값을 하나씩 꺼내온다.
끝으로 cdata 로 쿼리문을 감싸 >=, <= 를 문자열로 인식시켜 가격 값의 범위를 지정한다.
위의 쿼리가 정상적으로 실행 시 실제 쿼리문은 아래와 같을 것이다.
select * from clothes where brand = polyteru
and name like '%liso%'
and type in ('pant', 'shoes')
and min_cost >= 80000 and max_cost <= 120000
'Web Development > ETC' 카테고리의 다른 글
[Web Development] SMTP 프로토콜을 통한 메일 전송 및 인증 (0) | 2022.07.01 |
---|---|
[Web Programming] Checkbox 다중 값 전달 (0) | 2022.06.27 |
댓글