Contents
see List작성일 2014. 09. 29.
MyBatis Map이나 Bean 없이 2개 이상 파라미터 전달
MyBatis에서 Map이나 DTO Bean을 만들지 않고 여러 파라미터를 Mapper 메서드에 전달하는 방법입니다. 간단한 쿼리에서 불필요한 클래스 생성을 줄일 수 있습니다.
언제 사용하나요?
- 간단한 조회에서 2-3개 파라미터 전달
- DTO 클래스 생성이 과한 경우
- 페이징 처리 (offset, limit)
- 범위 검색 (startDate, endDate)
방법 1: @Param 어노테이션 (권장)
// Mapper 인터페이스
@Mapper
public interface UserMapper {
// 단일 파라미터는 @Param 생략 가능
User findById(Long id);
// 2개 이상은 @Param 필수
User findByEmailAndStatus(
@Param("email") String email,
@Param("status") String status
);
// 페이징
List<User> findAllWithPaging(
@Param("offset") int offset,
@Param("limit") int limit
);
// 날짜 범위
List<Order> findByDateRange(
@Param("startDate") LocalDate startDate,
@Param("endDate") LocalDate endDate,
@Param("status") String status
);
}
XML Mapper에서 사용
<!-- @Param으로 지정한 이름 그대로 사용 -->
<select id="findByEmailAndStatus" resultType="User">
SELECT * FROM users
WHERE email = #{email}
AND status = #{status}
</select>
<!-- 페이징 -->
<select id="findAllWithPaging" resultType="User">
SELECT * FROM users
ORDER BY created_at DESC
LIMIT #{limit} OFFSET #{offset}
</select>
<!-- 조건부 파라미터 -->
<select id="findByDateRange" resultType="Order">
SELECT * FROM orders
WHERE 1=1
<if test="startDate != null">
AND order_date >= #{startDate}
</if>
<if test="endDate != null">
AND order_date <= #{endDate}
</if>
<if test="status != null and status != '">
AND status = #{status}
</if>
</select>
방법 2: param1, param2 사용
// @Param 없이 순서로 접근
List<User> findByAgeRange(int minAge, int maxAge);
<!-- XML에서 param1, param2로 접근 -->
<select id="findByAgeRange" resultType="User">
SELECT * FROM users
WHERE age BETWEEN #{param1} AND #{param2}
</select>
<!-- 또는 arg0, arg1 (비권장) -->
<select id="findByAgeRange" resultType="User">
SELECT * FROM users
WHERE age BETWEEN #{arg0} AND #{arg1}
</select>
<!-- param1, param2는 가독성이 낮아 @Param 권장 -->
방법 3: Map 사용
// Map으로 전달
List<User> findByConditions(Map<String, Object> params);
// 호출
Map<String, Object> params = new HashMap<>();
params.put("status", "ACTIVE");
params.put("minAge", 20);
params.put("maxAge", 30);
List<User> users = mapper.findByConditions(params);
<!-- XML -->
<select id="findByConditions" resultType="User">
SELECT * FROM users
WHERE status = #{status}
AND age BETWEEN #{minAge} AND #{maxAge}
</select>
INSERT/UPDATE에서 사용
// 여러 파라미터로 UPDATE
int updateStatus(
@Param("id") Long id,
@Param("status") String status,
@Param("updatedBy") String updatedBy
);
<update id="updateStatus">
UPDATE users
SET status = #{status},
updated_by = #{updatedBy},
updated_at = NOW()
WHERE id = #{id}
</update>
// 조건부 INSERT
int insertIfNotExists(
@Param("email") String email,
@Param("name") String name
);
복잡한 조건 처리
<!-- 동적 IN 절 -->
List<User> findByIds(@Param("ids") List<Long> ids);
<select id="findByIds" resultType="User">
SELECT * FROM users
WHERE id IN
<foreach collection="ids" item="id"
open="(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- 여러 파라미터 + 리스트 -->
List<Order> findOrders(
@Param("userId") Long userId,
@Param("statuses") List<String> statuses
);
<select id="findOrders" resultType="Order">
SELECT * FROM orders
WHERE user_id = #{userId}
AND status IN
<foreach collection="statuses" item="status"
open="(" separator="," close=")">
#{status}
</foreach>
</select>
주의사항
- 파라미터가 3개 이상이면 DTO 클래스 권장
- @Param 이름과 XML 변수명 정확히 일치해야 함
- null 값 처리를 위한 조건문 추가 필요
- MyBatis 3.x 이상에서 @Param 사용 가능
spring
| No | 작성일 | Title |
|---|---|---|
| 2193 | 2026. 02. 11. | Spring WebSocket과 STOMP로 실시간 채팅 구현 |
| 2192 | 2026. 02. 11. | Spring Boot 3.5 신기능 완전 정리 |
| 2131 | 2026. 02. 11. | Testcontainers로 Spring 통합 테스트 자동화 |
| 2130 | 2026. 02. 11. | Spring Batch 5.x 대용량 데이터 처리 패턴 |
| 2129 | 2026. 02. 11. | Spring Modulith: 모듈러 모놀리스 아키텍처 |
| 2128 | 2026. 02. 11. | Spring Data JPA 쿼리 최적화 고급 기법 |
| 2127 | 2026. 02. 11. | GraalVM Native Image와 Spring Boot AOT 컴파일 |
| 2126 | 2026. 02. 11. | Spring Cloud Gateway로 API Gateway 구축하기 |
| 2125 | 2026. 02. 11. | Spring Security 6.x OAuth2/OIDC 실전 구현 |
| 2124 | 2026. 02. 11. | Virtual Thread와 Spring WebFlux 성능 비교 |