MyBatis에서 <foreach>
는 IN
조건이나 다중 INSERT
와 같이 반복적인 SQL을 작성할 때 아주 유용하게 쓰입니다. 하지만 이 안에서 item
을 여러 번 참조하거나, #{}
와 ${}
중 어떤 걸 써야 하는지 헷갈릴 수 있습니다. 이 글에서는 그 차이점과 실전에서 어떻게 써야 안전하고 효율적인지 정리해보겠습니다.
#{}
vs ${}
차이점
구분 | #{} |
${} |
---|---|---|
방식 | PreparedStatement 방식 | 문자열 치환 방식 |
용도 | 값 바인딩 (WHERE, VALUES 등) | 컬럼명, 테이블명 등 SQL 조각 삽입 |
장점 | SQL 인젝션 방지, 자동 타입 변환, 성능 최적화 | 동적인 SQL 문 구조 만들기 가능 |
단점 | 컬럼명/테이블명 등 SQL 구조에는 사용 불가 | SQL 인젝션 위험 있음, 성능 저하 가능 |
보안 | 안전 | 검증 없으면 매우 위험 |
예시 비교
<foreach collection="ids" item="id" separator=",">
#{id}
</foreach>
→ SELECT * FROM user WHERE id IN (?, ?, ?)
처럼 바인딩 처리됨
<foreach collection="ids" item="id" separator=",">
${id}
</foreach>
→ SELECT * FROM user WHERE id IN (1, 2, 3)
처럼 그대로 문자열로 치환됨
💡 결론: 대부분의 경우 #{}
를 사용하는 것이 안전하고 효율적입니다. ${}
는 컬럼명/테이블명 동적 변경처럼 특별한 상황에서만 써야 하며, 입력값 검증은 필수입니다.
<foreach>
에서 item
을 두 번 이상 사용하는 법
item
을 두 번 이상 쓰고 싶은 경우는 주로 다중 INSERT
구문에서 (#{item}, #{item})
처럼 같은 값을 반복해서 사용할 때입니다. 이때 사용할 수 있는 방법은 다음과 같습니다.
1. 객체의 속성을 이용 (추천)
<foreach collection="items" item="item" separator=",">
(#{item.id}, #{item.name})
</foreach>
각 item
이 객체라면 필드를 나눠서 얼마든지 참조할 수 있습니다. 예: List<Item>
형태로 넘기면 자연스럽게 여러 필드를 사용할 수 있어요.
2. 단순 값일 경우 #{item}
반복 사용
<foreach collection="items" item="item" separator=",">
(#{item}, #{item})
</foreach>
리스트 요소가 숫자나 문자열이면 이렇게 두 번 써도 문제 없습니다.
3. MyBatis 3.4 이상에서는 <bind>
로 변수화
<foreach collection="items" item="item" separator=",">
<bind name="v" value="item"/>
(#{v}, #{v})
</foreach>
복잡한 상황에서 중간 변수로 처리할 수 있어 유용합니다.
마무리
#{}
는 값 바인딩용 → 대부분의 경우 사용${}
는 SQL 조각 삽입용 → 컬럼명/테이블명 등 특수한 경우에만<foreach>
에서item
을 여러 번 써야 한다면 객체 사용을 고려하거나<bind>
활용
반응형
'Coding > Java' 카테고리의 다른 글
[Java] 사내망에서 Gradle 빌드 시 PKIX 인증서 오류 해결기 (feat. 프록시 & 인증서 등록) (0) | 2025.04.19 |
---|---|
[Java/SpringBoot] Kubernetes 환경에서 Spring Boot 로그를 Pod별로 Rolling 하도록 설정 (0) | 2025.04.19 |
[Java] 리스트의 요소가 다른 리스트에 포함되지 않는지 확인 (Collections.disjoint()) (1) | 2025.03.22 |
[Java] API 요청 및 응답 시 비동기 처리 (0) | 2024.12.30 |
[Java/JPA] JPQL 파라미터 바인딩 (위치 기반) (0) | 2024.04.11 |