[Java] MyBatis foreach에서 빈 배열이 들어올 경우 예외를 방지하는 방법

2025. 7. 20. 21:57·개발 (Development)/Java

Java에서 MyBatis를 사용할 때, foreach 구문에 빈 배열이나 리스트가 들어오는 상황은 종종 발생합니다. 이때 적절한 처리를 하지 않으면 SQL 문법 오류나 의도치 않은 전체 조회와 같은 문제가 생길 수 있습니다.

저는 최근 IN 절을 동적으로 구성하기 위해 <foreach> 태그를 사용하던 중, 전달받은 리스트가 빈 배열일 경우 SQL 오류가 발생하는 문제를 겪었습니다. 이 문제를 해결하기 위해 어떤 방식들이 있는지 조사하고, 실제로 적용해 보면서 가장 적합한 해결 방법을 찾게 되었습니다.

문제 상황: 빈 배열이 들어오면 SQL 오류 발생

예를 들어 아래와 같이 idList라는 리스트를 기반으로 사용자 정보를 조회하는 SQL을 구성한다고 가정합니다.

<select id="selectUserList" resultType="User">
  SELECT * FROM users WHERE id IN
  <foreach collection="idList" item="id" open="(" separator="," close=")">
    #{id}
  </foreach>
</select>

이때 idList가 비어 있다면, 생성된 SQL은 다음과 같이 됩니다.

SELECT * FROM users WHERE id IN ()

이는 SQL 문법상 허용되지 않기 때문에 오류가 발생하게 됩니다.

해결 방법 정리

이 문제를 해결하기 위해 다음과 같은 여러 방식을 검토하였고, 각각의 장단점을 파악했습니다.

1. Java 코드에서 사전 필터링

SQL을 실행하기 전에 Java 단에서 리스트가 비어 있는지 확인하고, 빈 결과를 반환하거나 실행을 생략하는 방식입니다.

if (idList == null || idList.isEmpty()) {
    return Collections.emptyList(); // 또는 사용자 정의 처리
} else {
    return userMapper.selectUserList(idList);
}
  • 장점: 가장 안전하고 예측 가능
  • 단점: 로직이 Java 단에 분산되어 MyBatis 쿼리와 분리됨

2. MyBatis <if> 조건문으로 감싸기

SQL 내부에서 리스트가 비어 있는지를 판단하여 foreach를 감쌀 수 있습니다.

<if test="idList != null and idList.size() > 0">
  AND id IN
  <foreach collection="idList" item="id" open="(" separator="," close=")">
    #{id}
  </foreach>
</if>
  • 장점: MyBatis XML 내부에서 제어 가능
  • 단점: 조건이 빠질 경우 전체 데이터가 조회되는 위험 있음

3. <choose>를 활용한 안전한 처리

가장 안전한 방식은 <choose> 태그를 활용하여 리스트가 비어 있을 경우 **무조건 false가 되는 조건(예: 1=0)**을 삽입하는 것입니다.

<choose>
  <when test="idList != null and idList.size() > 0">
    AND id IN
    <foreach collection="idList" item="id" open="(" separator="," close=")">
      #{id}
    </foreach>
  </when>
  <otherwise>
    AND 1 = 0
  </otherwise>
</choose>
  • 장점: 리스트가 비어도 SQL 문법 오류 없이 안전하게 동작
  • 단점: 쿼리 길이가 다소 길어짐

결론: 실무에서는 <choose> 방식이 가장 안전

여러 방식을 직접 테스트해 본 결과, 실무에서는 빈 리스트일 경우 자동으로 무조건 실패하는 조건을 삽입하는 <choose> 방식이 가장 예측 가능하고 안전했습니다. 특히 API 요청에 따라 리스트가 동적으로 결정되는 상황이라면, 이 방식이 SQL 오류를 방지하면서도 정확한 제어가 가능합니다.

반응형

'개발 (Development) > Java' 카테고리의 다른 글

[Java] PostgreSQL의 timestamptz를 Java MyBatis에서 Instant로 받는 방법  (2) 2025.07.28
[Java] ISO 8601 형식의 시간 출력하기 (현재 시간과 과거 시간 구하기)  (2) 2025.07.20
[Java/SpringBoot] 서버 간 API 호출 오류: Connection reset 에러 분석 및 해결 방법  (0) 2025.07.13
[Java] LinkedHashMap에서 특정 값을 가진 항목 제거하는 방법  (0) 2025.07.05
[Java/SpringBoot] Spring OAuth2 시스템에서 발생한 Access Token 만료 및 인증 오류 대응 기록  (2) 2025.06.28
'개발 (Development)/Java' 카테고리의 다른 글
  • [Java] PostgreSQL의 timestamptz를 Java MyBatis에서 Instant로 받는 방법
  • [Java] ISO 8601 형식의 시간 출력하기 (현재 시간과 과거 시간 구하기)
  • [Java/SpringBoot] 서버 간 API 호출 오류: Connection reset 에러 분석 및 해결 방법
  • [Java] LinkedHashMap에서 특정 값을 가진 항목 제거하는 방법
LoopThinker
LoopThinker
모르는 것을 알아가고, 아는 것을 더 깊게 파고드는 공간
  • LoopThinker
    CodeMemoir
    LoopThinker
  • 전체
    오늘
    어제
    • 분류 전체보기 (231)
      • 개발 (Development) (165)
        • Algorithm (1)
        • Angular (1)
        • AWS (6)
        • DeepSeek (2)
        • Docker (7)
        • Git (3)
        • Java (34)
        • JavaScript (4)
        • Kafka (5)
        • Kubernetes (4)
        • Linux (7)
        • PostgreSQL (38)
        • Python (31)
        • React (3)
        • TypeScript (3)
        • Vue.js (5)
        • General (11)
      • 데이터 분석 (Data Analysis) (1)
      • 알고리즘 문제 풀이 (Problem Solving.. (27)
      • 자격증 (Certifications) (24)
        • ADsP (14)
        • 정보처리기사 (4)
        • Linux Master (5)
        • SQLD (1)
      • 기술 동향 (Tech Trends) (11)
      • 기타 (Others) (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    JPA
    javascript
    timescaledb
    Kafka
    java
    JSON
    리눅스 마스터 2급
    백준자바
    백준온라인저지
    Vue.js
    AWS
    python
    pandas
    PostgreSQL
    DevOps
    springboot
    Spring boot
    백준
    데이터분석
    오답노트
    Linux master
    Kubernetes
    ADsP
    deepseek
    MyBatis
    docker
    백준알고리즘
    자바
    리눅스 마스터 2급 2차
    Linux
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
LoopThinker
[Java] MyBatis foreach에서 빈 배열이 들어올 경우 예외를 방지하는 방법
상단으로

티스토리툴바