ETC

[MyBatis] if와 foreach를 활용하여 동적 쿼리생성 (필터링 기능)

zamezzz 2019. 12. 18. 22:49

● MyBatis - if와 foreach를 활용하여 동적 쿼리 생성

MyBatis에서 if와 foreach를 활용하여 동적 쿼리를 생성하는 방법에 대해 정리하겠습니다.

 

그리고 이를 이용하면 간단한 검색 필터링 기능을 쉽게 구현할 수 있습니다.

 

이 내용에 대한 예제를 통해 간단히 정리해보겠습니다.

 

■ MyBatis에서의 if와 foreach

 

먼저 MyBatis에서의 if와 foreach에 대해 살펴보겠습니다.

 

이름 그대로 if는 조건문이며, foreach는 반복문에서 사용됩니다.

 

사용방법은 다음과 같습니다. 해당 조건에 참일 경우만 내부의 쿼리문이 더해집니다.

 

<if test="param1 != null">

  {QUERY 문}

</if>

 

다음으로 foreach의 사용법은 다음과 같습니다.

 

collection에는 전달받은 파라미터값이 들어가며, item은 실제 쿼리문에서 사용할 값의 이름입니다.

open과 close는 각각 쿼리에서 시작과 끝에 들어 갈 값이며, separator은 구분자를 뜻합니다.

 

<foreach collection="param_list" item="item" index="index" separator="," open="(" close=")" >

  #{item}

</foreach>

 

 

■ if와 foreach를 이용한 쿼리 예제 

 

간단한 사용방법은 위에서 설명을 드렸습니다.

 

그럼 실제로 if와 foreach를 이용하여 어떻게 동적 쿼리를 생성할 수 있는지 보겠습니다.

 

이를 위해 위에서 말씀드린대로 검색 필터링 기능을 예시로 설명을 드리겠습니다.

 

예시를 위해 먼저 아래 내용을 가정하겠습니다.

 

보통 대부분 쇼핑몰에 있는 필터를 생각하시면 이해가 빠르실 것 같은데요. 아래 그림입니다.

 

출처 : Daum 쇼핑하우

 

저는 간단한 예제이므로 색깔과 브랜드 2가지의 파라미터만 있다고 가정하겠습니다.

 

먼저 Controller 소스입니다.

@RequestMapping("/filter")

public Object exampleMethod() {

  List<String> colorList = new ArrayList<>();

  colorList.add("red");

  colorList.add("black");

  

  List<String> brandList = new ArrayList<>();

  brandList.add("brand1");

 

  Map<String, Object> param = new HashMap<>();

  param.put("color_list", colorList);

  param.put("brand_list ", brandList );

 

  return filterMapper.getList(param);

}

임의로 colorList와 brandList라는 리스트 변수를 선언하여 값을 add하였습니다.

 

실제로는 클라이언트에서 이 값을 받으면 될 것 같습니다.

 

그리고 각 리스트는 param Map을 만들어 여기에 추가하였습니다.

 

그리고 마지막으로 필터된 리스트 검색을 위해 filterMapper의 함수를 호출하였습니다.

 

다음으로는 filterMapper.java 소스입니다.

List<ProductDto> getList(Map<String, Object> param);

 

마지막으로는 filterMapper.xml 소스입니다. 실제 쿼리문은 여기서 만들어집니다.

<select id="getList" resultType="productDto" parameterType="java.util.HashMap">

  select *

  from product_info

  where product_status=1

  <if test="color_list.size != 0">

    and color in 

    <foreach collection="color_list" item="item" index="index" separator="," open="(" close=")">

      #{item}

    </foreach>

  </if>

  <if test="brand_list.size != 0">

    and brand in 

    <foreach collection="brand_list" item="item" index="index" separator="," open="(" close=")">

      #{item}

    </foreach>

  </if>

</select>

 

위와 같이 작성을 한다면 먼저 color_list와 brand_list의 크기를 확인하여 값이 들어 있다면 해당 쿼리를

 

추가합니다. 만약 0이라면 해당 쿼리는 추가되지 않습니다.

 

위 쿼리가 정상적으로 실행된다면 아래와 같은 쿼리가 실행될 것입니다.

  select *

  from product_info

  where product_status=1

    and color in ('red', 'black')

    and brand in ('brand1'

 

 

이러한 방식으로 간단한 동적 쿼리를 생성할 수 있습니다.

 

그리고 이를 이용하면 필터링 검색을 쉽게 할 수 있습니다.

 

그럼 글을 마치겠습니다. 감사합니다.

반응형