회사 프로젝트에서 공휴일 정보를 외부 API로 받아 Oracle DB에 저장하는 기능을 개발하던 중 예상치 못한 문제를 만났습니다.
API 응답에는 다음과 같이 Boolean 형태의 값이 포함되어 있었습니다.
{
"yyyymmdd": "20260527",
"isHoliday": true
}
DB에는 공휴일 여부를 문자 코드로 저장해야 했기 때문에 다음과 같은 형태로 저장하려고 했습니다.
| true | H |
| false | N |
처음에는 Oracle SQL의 CASE 문을 이용해 간단하게 처리할 수 있을 것이라 생각했습니다.
SELECT CASE
WHEN TRUE THEN 'H'
ELSE 'N'
END
FROM DUAL;
하지만 실행 결과는 오류였습니다.
Oracle에서는 TRUE/FALSE를 사용할 수 없다
많은 개발자가 처음 Oracle을 접할 때 당황하는 부분 중 하나입니다.
Java에서는 Boolean 타입을 자유롭게 사용할 수 있지만 Oracle SQL에서는 TRUE, FALSE를 직접 사용할 수 없습니다.
즉 아래 SQL은 Oracle에서 실행되지 않습니다.
SELECT TRUE FROM DUAL;
SELECT CASE WHEN TRUE THEN 'H' END
FROM DUAL;
Oracle의 BOOLEAN 타입은 PL/SQL 영역에서만 사용할 수 있으며 일반 SQL에서는 사용할 수 없습니다.
처음 작성했던 MyBatis 코드
MERGE INTO를 사용하여 데이터를 저장하고 있었습니다.
<foreach collection="list"
item="item"
separator="UNION ALL">
<![CDATA[
SELECT #{item.yyyymmdd} WORK_DATE
, #{item.isHoliday} WORK_CD
, SYSDATE CREATE_DT
FROM DUAL
]]>
</foreach>
하지만 이렇게 작성하면 Boolean 값이 그대로 전달됩니다.
원하는 값은 H 또는 N 이므로 추가 처리가 필요했습니다.
MyBatis choose 문으로 해결
가장 깔끔한 방법은 MyBatis의 동적 SQL 기능을 사용하는 것입니다.
<foreach collection="list"
item="item"
separator="UNION ALL">
<![CDATA[
SELECT #{item.yyyymmdd} WORK_DATE
]]>
<choose>
<when test="item.isHoliday">
<![CDATA[
,'H' WORK_CD
]]>
</when>
<otherwise>
<![CDATA[
,'N' WORK_CD
]]>
</otherwise>
</choose>
<![CDATA[
,SYSDATE CREATE_DT
FROM DUAL
]]>
</foreach>
동작 결과
API 응답
{
"isHoliday": true
}
생성 SQL
SELECT '20260527' WORK_DATE,
'H' WORK_CD,
SYSDATE CREATE_DT
FROM DUAL
API 응답
{
"isHoliday": false
}
생성 SQL
SELECT '20260527' WORK_DATE,
'N' WORK_CD,
SYSDATE CREATE_DT
FROM DUAL
원하는 결과를 얻을 수 있습니다.
Java에서 미리 변환하는 방법도 있다
Mapper에서 처리하지 않고 Service 계층에서 미리 변환할 수도 있습니다.
item.setWorkCd(
item.isHoliday() ? "H" : "N"
);
그리고 Mapper에서는 단순하게 사용합니다.
SELECT #{item.workCd}
FROM DUAL
대량 처리나 복잡한 SQL에서는 이 방법도 상당히 많이 사용됩니다.
정리
Oracle SQL은 TRUE/FALSE를 직접 지원하지 않습니다.
따라서 MyBatis에서 Boolean 값을 저장해야 할 경우 다음 방법을 사용하는 것이 좋습니다.
- MyBatis <choose> 사용
- Java에서 미리 H/N 변환
- SQL에서 TRUE/FALSE 직접 사용 금지
- Oracle CASE WHEN TRUE 구문 사용 불가
Oracle과 MyBatis를 함께 사용하는 프로젝트라면 한 번쯤 만나게 되는 문제이므로 기억해 두면 개발 시간을 아낄 수 있습니다.
'dev > java(egov)' 카테고리의 다른 글
| java mybatis 프로시저 호출 (0) | 2025.02.18 |
|---|---|
| java 윤년 계산기 (0) | 2025.01.27 |
| java 16진수 색상 표현 RGB (2) | 2025.01.27 |
| java int to hex (0) | 2025.01.26 |
| Bean 중 하나를 @Primary로 표시하거나, 여러 Bean을 허용하도록 소비자를 업데이트하거나, 소비해야 하는 Bean을 식별하기 위해 @Qualifier를 사용하는 것을 고려하세요. (1) | 2024.12.25 |