들어가며
현재 투입되어있는 프로젝트의 서비스 중에는 특정 데이터를 조회할 수 있는 화면이 있습니다.
그런데 이 화면을 사용하게되는 업무 특성상 데이터를 일일이 하나씩 조회하기가 번거롭다는 불편사항이있어
이를 한번에 다중 검색 가능하도록 수정 조치하였고, 당시 작업내용을 핵심부분만 간략하게 정리하였습니다.
기존 방식
- mapper.xml
<sql id="ticketSearch">
<if test="(method_info != null and method_info != '')">
<if test="method_id == 'gkId'">
AND GK_ID = #{method_info}
</if>
<if test="method_id == 'parentTicketId'">
AND UPPER(PRNT_TKT_ID) LIKE CONCAT('%',UPPER(REPLACE(#{method_info}, '_', '#_')),'%') ESCAPE '#'
</if>
<if test="method_id == 'ticketId'">
AND UPPER(TKT_ID) LIKE CONCAT('%',UPPER(REPLACE(#{method_info}, '_', '#_')),'%') ESCAPE '#'
</if>
<if test="method_id == 'guid'">
AND GUID LIKE CONCAT('%',#{method_info},'%')
</if>
</if>
</sql>
<select id="list" parameterType="map" resultMap="ticketVO">
SELECT
컬럼 1,
컬럼 2,
컬럼 3
FROM
테이블 A
WHERE
DEL_YN_FG = 'N'
<include refid="ticketSearch"/>
</select>
▲ 화면에서 입력한 문자열 1개를 포함하고있는 데이터를 “like” 검색을 통한 단일 조회 방식
작업 내용
검색하고자하는 데이터의 종류가
"gkId", "parentTicketId", "ticketId"중 하나일 경우, 화면에서 검색어 입력 시 구분자(콤마(”,”) 혹은 공백(” ”))를 기준으로 각각의 검색어를 “포함”하는 데이터를 전체 조회하도록 수정MyBatis foreach > “separator"를 활용한 OR 조건 동적 쿼리 적용
service.java (로직 추가)
protected void setMultipleSearchInfo(Map<String, Object> reqMap){
String method_info = GkUtils.nvl(reqMap, METHOD_INFO);
String method_id = GkUtils.nvl(reqMap, METHOD_ID);
if( !(Arrays.asList("gkId", "parentTicketId", "ticketId").contains(method_id))
&& StringUtil.isEmpty(method_info)) return;
method_info = method_info.replaceAll("\\s{2,}", " ").trim();
String[] splitStr = method_info.split("[\\s,]+");
if("gkId".equals(method_id)){
splitStr = Arrays.stream(splitStr)
.map(str -> GkUtils.getPlainGkId(str))
.toArray(String[]::new);
}
reqMap.put("method_info_list", splitStr);
}
특정 카테고리 여부 체크
구분자 기준으로 split → String[] 타입 파라미터에 Set
mapper.xml (MyBatis 동적 쿼리 적용)
<sql id="ticketSearch">
<if test="(method_info != null and method_info != '')">
<if test="method_id == 'gkId'">
<choose>
<when test="method_info_list != null and method_info_list.length > 1">
AND
<foreach collection="method_info_list" item="item" open="(" close=")" separator="OR">
GK_ID LIKE CONCAT('%', REPLACE(#{item}, '_', '#_'), '%') ESCAPE '#'
</foreach>
</when>
<otherwise>
AND GK_ID = #{method_info}
</otherwise>
</choose>
</if>
<if test="method_id == 'parentTicketId'">
<choose>
<when test="method_info_list != null and method_info_list.length > 1">
AND
<foreach collection="method_info_list" item="item" open="(" close=")" separator="OR">
PRNT_TKT_ID LIKE CONCAT('%', REPLACE(#{item}, '_', '#_'), '%') ESCAPE '#'
</foreach>
</when>
<otherwise>
AND PRNT_TKT_ID LIKE CONCAT('%',REPLACE(#{method_info}, '_', '#_'),'%') ESCAPE '#'
</otherwise>
</choose>
</if>
<if test="method_id == 'ticketId'">
<choose>
<when test="method_info_list != null and method_info_list.length > 1">
AND
<foreach collection="method_info_list" item="item" open="(" close=")" separator="OR">
TKT_ID LIKE CONCAT('%', REPLACE(#{item}, '_', '#_'), '%') ESCAPE '#'
</foreach>
</when>
<otherwise>
AND TKT_ID LIKE CONCAT('%',REPLACE(#{method_info}, '_', '#_'),'%') ESCAPE '#'
</otherwise>
</choose>
</if>
<if test="method_id == 'guid'">
AND GUID LIKE CONCAT('%',#{method_info},'%')
</if>
</if>
</sql>
<select id="list" parameterType="map" resultMap="ticketVO">
SELECT
컬럼 1,
컬럼 2,
컬럼 3
FROM
테이블 A
WHERE
DEL_YN_FG = 'N'
<include refid="ticketSearch"/>
</select>