Mapper를 이용해서 쿼리를 보낼 때, 조건부로 쿼리를 붙여야하는 경우가 있다.
예를 들어, '전체보기' , '날짜필터링', '그룹필터링', '권한필터링'.. 이런 메뉴가 있다고 할때,
사용자가 가능한 선택은 전체보기나 날짜만으로 필터링 또는 날짜+권한 이런식으로 선택이 가능하다고 할때,
다음과 같이 조건이 필요해질 수 있다.
WHERE뒤에.. 전체보기면 그냥 통과, 그룹필터링이면 table.GroupCode in ('GroupA', 'GroupB') 이렇게, 권한필터링이면 table.AuthorCode in ('Admin1', 'admin2')... 권한과 그룹을 같이 적용하는 경우에는 table.GroupCode in ('GroupA', 'GroupB') AND table.AuthorCode in ('Admin1', 'admin2')
이렇게 쿼리가 나와야 할 것이다.
이걸 어떻게하면 좋을까?
1. 단순히 case by case로 하나하나 Mapper의 item을 만든다.
-> 구현난이도 상. (로직상으로는 단순하지만 코딩노가다가 엄청나다.). 단순반복작업으로 같은 쿼리를 여러개 만들어야한다. 물론, 테이블의 컬럼이 바뀌거나 추가될 경우. 단순 반복작업을 여러번 해야한다. 단순 수치적으로만 생각해봐도 선택가능한 항목을 4개정도로 제한해도, 4C1(4) + 4C2 (6)+ 4C3 (4) + 1(4C4)의 가짓수가 나온다. 쿼리하나만 바꾸어도 15개의 쿼리가 바뀌어야하는 마법과같은일(...)이 일어난다.
물론 단순작업에 따른 두뇌와 손가락의 지침과, 졸림. 그로인한 실수와 그 실수로 인한 버그, 버그수정 재배포를 통한 밤새기 시작하는 준비.. 의 과정은 덤이다.
2. 쿼리문 안에서 해보기..
복잡하다. 그리고 경우에 따라서는 만들수가 없는 경우가 당연히 발생한다.
3. xml mapper안에서 수정해보기.
MyBatis에서는 친절하게도, 지원을 해준다. 아래 구문으로.
SELECT
a.id,
a.ab
FROM
mytable a
WHERE
1=1
<if test="val gt 1">
AND a.id= 'hello'
</if>
위에서처럼
<if test="계산식" >
조건부 SQL구문
</if>
이렇게 하면 된다.
계산식 안에서 문자열 일치 여부는 ==로 진행하면 된다.
만약 숫자 비교를 해야한다면, >, <도 가능하다만..
greater then -> A gt 1, less tnen-> A lt 2
이런식으로 처리할 수 있다.
댓글