MyBatis 사용 시 SQL 내 CDATA[...]의 의미
문제점 😅
XML 파일로 구성된 쿼리 파일을 정신없이 수정하다 보면, DB툴에서도 잘 작동하고, 쿼리문은 멀쩡한데 에러가 발생하는 경우를 종종 겪게 된다. 경험 중 부등호 때문에 에러가 발생한 경우가 종종 있었는데 이런 경우에 사용한 <![CDATA[...]]>
에 대해 몇 자 적어둔다.
해결책 😏
<![CDATA[...]]>
의 CDATA의 의미는, Character DATA로 문자형 데이터를 의미한다. 안에 입력된 문장은 파싱되지 않고 그대로 문자열로 출력된다. MyBatis에서 Mapper File은 XML로 작성되어 있고, 파싱될 때 XML 표준으로 파싱된다. 그래서 쿼리 내의 부등호(<,>)가 태그로 인식되어 에러가 발생하므로 파싱되지 않도록 처리해야 한다. 참고로 MyBatis의 XML문은 세미콜론(;)이 있으면 안된다!
BAD
WHERE절과 AND절 부등호가 <![CDATA[...]]>
로 감싸지 않았기 때문에 파싱 에러 발생.
SELECT /* [CommonDao.selectFruitName][byeoom][과일명 조회] */
FRUIT_NAME
FROM FRUIT_BASKET
WHERE AMOUNT < #{amount}
AND PRICE >= #{price}
따라서 상기 쿼리의 올바른 수정은 다음과 같다.
1. SQL문 전체를 감싸는 방법
<![CDATA[
SELECT /* [CommonDao.selectFruitName][byeoom][과일명 조회] */
FRUIT_NAME
FROM FRUIT_BASKET
WHERE AMOUNT < #{amount}
AND PRICE >= #{price}
]]>
이 경우 작성한 SQL을 복사해서 DB툴에서 바로 실행하기 용이하다.
2. 부등호를 포함한 절마다 감싸는 방법
SELECT /* [CommonDao.selectFruitName][byeoom][과일명 조회] */
FRUIT_NAME
FROM FRUIT_BASKET
WHERE AMOUNT <![CDATA[<]]> #{amount}
AND PRICE <![CDATA[>=]]> #{price}
부등호가 쿼리 내에 하나만 존재하는 경우 나는 이 방법으로 작성한다.
3. 부등호 코드값으로 작성하는 방법
SELECT /* [CommonDao.selectFruitName][byeoom][과일명 조회] */
FRUIT_NAME
FROM FRUIT_BASKET
WHERE AMOUNT < #{amount}
AND PRICE ≥ #{price}
직관적이지 않으므로 추천하지 않는다. 부등호 코드값은 아래를 참고한다.
<
:<
>
:>
<=
:≤
>=
:≥
마무리 😎
파싱 에러 발생 시, SQL 내 조건절에 부등호가 <![CDATA[...]]>
안에 작성되어있는지 확인하고, 부등호는 <![CDATA[...]]>
안에 작성하는 습관을 들이자.
참고문헌 📝
https://choicode.tistory.com/33
https://thenicesj.tistory.com/285