wintertreey 님의 블로그

[Mybatis] 동적 쿼리, 컨트롤 플래그(가상 파라미터) 본문

SQL과 DB

[Mybatis] 동적 쿼리, 컨트롤 플래그(가상 파라미터)

wintertreey 2025. 5. 23. 16:25

COALESCE  

COALESCE(칼럼1, 칼럼2, ...) FROM TABLE;

칼럼1이 NULL이 아니면 칼럼1반환, NULL이면 칼럼2반환.

칼럼2이 NULL이 아니면 칼럼2반환, NULL이면 칼럼3반환.

....

 

WHERE 

TRUE와 if 조건

WHERE
        true
        <if test="col1 != null and col1 != ''">
            AND A.COL1 = #{col1}
        </if>
        <if test="col2 != null and col2 != ''">
            AND A.COL2 = #{col2}
        </if>
        <if test="col3 != null and col3 != ''">
            AND A.COL3 = (서브쿼리결과)
        </if>

 

이처럼 if 조건을 사용하여 동적쿼리를 생성할 수 있다.

 

true, 1=1과 같은 조건을 적어주는 이유.

만약 if 구문의 조건에 아무것도 해당되지 않는다면, where 구문은 불필요하게 되어 구문상의 문법오류가 발생.

그럴 경우를 대비하여 true나 1=1과 같은 아무탈없는 조건을 상단에 기입해주게 된다. 

 

 

 

 


마주한 문제상황.

해당 쿼리문에 조건을 추가하여 어떤 상황에선 나오는 결과값을 다르게 하고자 했다.

 

그냥 막무가내로 아무 조건없이 WHERE 구문에 조건을 추가하고자했다.

근데 call hierarchy로 확인해보니, 해당 쿼리를 불러다 쓰는 상황이 이 문제상황외에도 여럿임을 확인.

(마우스 오른쪽버튼으로 확인, 혹은 CTRL ALT H)

그래서 함부로 아무 조건없이(if구문없이) 

AND BLA~BLA~ 를 걸 수가 없다는걸 알았다. 

 

1. 원하는 결과를 위한 조건 탐색 : SELECT 구문에 있는 서브쿼리로 만들어진 가상의 칼럼을 WHERE 조건에서 사용하려고 시도. 

 

스칼라 서브쿼리 = SELECT 에서 사용하는 서브쿼리. 

스칼라 서브쿼리에서 만든 가상칼럼은 WHERE 조건절에서 사용할 수 없다. 

 

... 다른 방법은 없을까?

 

2. 해당 쿼리를 불러 쓰는 로직(범위) 보다 명확히 확인. 

controller 3 > service 1 에서 해당 로직을 불러다 쓸 때 내가 원하는 조건만을 추가하면 된다는것을 확인했다. 

 

가상 파라미터 혹은 컨트롤 플래그라고 불리며 쿼리에서만 사용되고 DB에는 없는 필드를 생성한다. 

 

service에서 mapper로 넘겨주는 로직에서 map에 추가해준다. 

 

//Service
@Transactional
	public List<Map<String, Object>> getMemberList(Map<String,Object> paramMap) throws Exception {
		paramMap.put("seoulonly", "Y");
		List<Map<String, Object>> list = membersMapper.searchMembers(paramMap);
		return list;
	}

 

seoulonly 는 DB 상에는 없는 칼럼. 임의로 가상 필드를 생성한다.

 

<!-- mapper.xml -->
select id="searchMembers" resultType="어쩌구저쩌구.ResultMap" parameterType="map">
    SELECT 
        A.*,
    FROM MEMBERS A
    WHERE
        true
        <if test="seoulonly == 'Y'">
        	AND A.CITY = '02'
        </if>
        <if test="phone != null and phone != ''">
            AND A.PHONE = #{phone}
        </if>

 

생성한 가상 파라미터를 동적 조건에 추가하여 조건을 생성한다.

 

 

3. mybatis mapper numberformatexception에러

한 글자만 있을경우 분명 글자임에도 char로 인식한다고 한다.

여러 방법 중 나는 홑따옴표('') 에서 쌍따옴표("")로 바꿔주었다. 

 

 

<!-- mapper.xml -->
select id="searchMembers" resultType="어쩌구저쩌구.ResultMap" parameterType="map">
    SELECT 
        A.*,
    FROM MEMBERS A
    WHERE
        true
        <if test='seoulonly == "Y"'>
        	AND A.CITY = '02'
        </if>
        <if test="phone != null and phone != ''">
            AND A.PHONE = #{phone}
        </if>

 

 

 

※ 해당 코드는 원 작업의 일부분을 수정하여 원본과 동일하지 않습니다. 

작업물을 보호하고자 한 조치로, 참고만 하시길 바랍니다. 

 


https://wnwa.tistory.com/35

 

[MySQL] COALESCE 함수로 NULL 값 처리하기 (feat. IFNULL 차이점)

기본 사용법 SELECT COALESCE(칼럼1, 칼럼2, 칼럼3, ... , 칼럼 N, ...) FROM table; 칼럼1이 NULL이 아니면 칼럼1을 반환되고 NULL이면 칼럼2를 반환. 칼럼2가 NULL이 아니면 칼럼2를 반환하고 칼럼1과 칼럼2 모두 N

wnwa.tistory.com

https://mjn5027.tistory.com/51

 

[ Oracle ] SQL 서브쿼리 SELECT, FROM, WHERE

서브쿼리란? - 하나의 쿼리 문장 내에 포함된 또 하나의 쿼리 문장. - 비교연산자의 오른쪽에 기술해야 하고 반드시 괄호 안에 넣어야 함. - 메인 쿼리가 실행되기 이전에 한 번만 실행됨. SQL의 기

mjn5027.tistory.com

https://save-idea.tistory.com/47

 

[마이바티스] MyBatis Mapper NumberFormatException 에러

◆ 발생에러Cause: java.lang.NumberFormatException: For input string: "Y" MyBatis Mapper 파일(xml)에서 위와 같은 에러 발생했다.문제가 되는 구문은 아래의 조건문인데 eml_trms_agre_yn = #{emlTrmsAgreYn} eml_trms_agre_yn 컬

save-idea.tistory.com

 

 

 

'SQL과 DB' 카테고리의 다른 글

다대다 관계 N:N  (0) 2025.05.16