본문 바로가기

dev/java(egov)

MyBatis Boolean 값(H/N) 변환하기! Oracle MERGE에서 true/false 처리 방법

반응형

회사 프로젝트에서 공휴일 정보를 외부 API로 받아 Oracle DB에 저장하는 기능을 개발하던 중 예상치 못한 문제를 만났습니다.

API 응답에는 다음과 같이 Boolean 형태의 값이 포함되어 있었습니다.

{
    "yyyymmdd": "20260527",
    "isHoliday": true
}
 

DB에는 공휴일 여부를 문자 코드로 저장해야 했기 때문에 다음과 같은 형태로 저장하려고 했습니다.

isHoliday저장값
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를 함께 사용하는 프로젝트라면 한 번쯤 만나게 되는 문제이므로 기억해 두면 개발 시간을 아낄 수 있습니다.

반응형