디자인을 수정하면서 목록 검색 방법을 바꿨다. 원래 출장자 이름, 출장일 둘 중에 하나만 골라 키워드를 검색하는 방식이었는데, 키워드 검색은 출장자 이름, 출장 장소 2가지를 제공하고 출장일 기준을 따로 제공해서 출장일 & 키워드 2가지 기준 검색이 가능하도록 변경했다.
출장 리스트를 가져오는 쿼리와 출장 정보 개수를 가져오는 쿼리의 방식이 약간 달라서 같은 검색 방식을 적용하는 데 어려움이 있었다. 출장 리스트에선 출장 정보의 출장자 이름들을 GROUP_CONCAT()
으로 합쳐서 하나의 string으로 가져오기 때문에 HAVING
을 사용하면 출장자 이름 검색이 수월했다.
<select id="selectBtList" parameterType="searchVO" resultType="egovMap">
SELECT
BT_ID,
LOCATION,
TRIP_START_DATE,
TRIP_END_DATE,
(SELECT GROUP_CONCAT(EMP.EMP_Name SEPARATOR ', ')...
) AS TRAVELER_NAME
FROM BUSINESSTRIP AS BT
WHERE 1=1
<if test="searchTripDate!=null and searchTripDate != ''">
AND #{searchTripDate} BETWEEN TRIP_START_DATE AND TRIP_END_DATE
</if>
<if test="searchKeyword != null and searchKeyword != ''">
<choose>
<when test="searchCondition == 1">
AND LOCATION LIKE CONCAT('%', #{searchKeyword} ,'%')
</when>
<when test="searchCondition == 0">
HAVING TRAVELER_NAME LIKE CONCAT('%', #{searchKeyword} ,'%')
</when>
</choose>
</if>
ORDER BY CREATED_AT DESC
LIMIT #{recordCountPerPage} OFFSET #{firstIndex}
</select>
그러나 출장 정보 개수는 select할 값은 count 하나인데 검색 시 출장자 이름 정보가 필요한 것이 문제였다. 그래서 select에 서브쿼리를 넣는 것이 아니라 from에 서브쿼리로 필요한 컬럼만 모은 테이블을 생성한 후 그 테이블의 모든 컬럼을 count하는 방식을 생각해냈다.
<select id="selectBtListTotCnt" parameterType="searchVO" resultType="int">
SELECT COUNT(*) totcnt
FROM (SELECT
BT.BT_ID,
USER_ID,
EMP_NAME,
TRIP_START_DATE,
TRIP_END_DATE,
LOCATION
FROM BUSINESSTRIP AS BT
LEFT JOIN BUSINESSTRIP_ROLES AS BTR ON BT.BT_ID = BTR.BT_ID
LEFT JOIN EMPLOYEE AS EMP ON BTR.USER_ID = EMP.EMP_NO
WHERE USER_TYPE=0) BT
WHERE 1=1
<if test="searchTripDate!=null and searchTripDate != ''">
AND #{searchTripDate} BETWEEN TRIP_START_DATE AND TRIP_END_DATE
</if>
<if test="searchKeyword != null and searchKeyword != ''">
<choose>
<when test="searchCondition == 1">
AND LOCATION LIKE CONCAT('%', #{searchKeyword} ,'%')
</when>
<when test="searchCondition == 0">
AND EMP_NAME LIKE CONCAT('%', #{searchKeyword} ,'%')
</when>
</choose>
</if>
</select>
새로운 검색 조건을 추가하기 위해 기존에 사용하던 egov 샘플인 'SampleDefaultVO'에 다른 속성을 추가할 필요가 있었다. 기존 파일을 수정하지 않기 위해 'BtDefaultVO' 클래스를 새로 만들어 기존 VO를 상속한 뒤 새로운 검색 조건 속성을 추가했다.
public class BtDefaultVO extends SampleDefaultVO {
/** 출장일 검색 */
private String searchTripDate = "";
}