Java/MyBatis
MyBatis에 인자를 넘기는 다양한 방법
Ethan Kang
2016. 11. 22. 19:43
반응형
0. 예제 테이블 구조
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(40) NOT NULL,
email VARCHAR(100),
age INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
1. 객체로 넘기기
1‑1. Java 코드
// User.java (Lombok 예시)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String username;
private String email;
private Integer age;
}
1‑2. Mapper 인터페이스
@Mapper
public interface UserMapper {
int insertUser(User user);
User findById(Integer id);
}
1‑3. XML 매핑
<insert id="insertUser" parameterType="com.example.User">
INSERT INTO users(username, email, age)
VALUES (#{username}, #{email}, #{age})
</insert>
<select id="findById" parameterType="int" resultType="com.example.User">
SELECT id, username, email, age, created_at
FROM users
WHERE id = #{id}
</select>
장점
- IDE 자동 완성 & 컴파일 타임 타입 검증
- 필드가 많아져도 메서드 시그니처가 깔끔
주의사항
- 같은 DTO를 여러 쿼리에서 재사용할 때 N+1 필드 문제(필요 없는 칼럼 포함) 발생 가능
- 필드명이 컬럼명과 다른 경우 resultMap을 별도로 정의해야 함
2. HashMap<String, Object>
로 넘기기
2‑1. 자바 호출부
Map<String, Object> params = new HashMap<>();
params.put("username", "eunseok");
params.put("minAge", 25);
List<User> list = userMapper.findByNameAndMinAge(params);
2‑2. XML 매핑
<select id="findByNameAndMinAge"
parameterType="hashmap"
resultType="com.example.User">
SELECT *
FROM users
WHERE username = #{username}
AND age >= #{minAge}
</select>
장점
- 동적 칼럼/조건 조합이 필요할 때 유연
- 별도 DTO 생성 없이 빠르게 시도 가능
단점
- 타입 안전성 없음 (런타임 오류, 오타 찾기 어려움)
- 컬럼 수가 많아질수록 가독성 급감
3. 원시형(Primitive) 또는 단일 값으로 넘기기
3‑1. 하나의 파라미터만 필요할 때
User user = userMapper.findByUsername("eunseok");
<select id="findByUsername"
parameterType="string"
resultType="com.example.User">
SELECT *
FROM users
WHERE username = #{value}
</select>
#{value}
또는#{_parameter}
로 이름 없이 참조합니다.
Tip: 파라미터 이름이 딱 하나면 어떤 타입이든#{value}
로만 접근 가능합니다.
3‑2. 둘 이상의 프리미티브를 넘길 때 @Param
활용
@Select("""
SELECT *
FROM users
WHERE username = #{username} AND age >= #{age}
""")
List<User> search(@Param("username") String username,
@Param("age") int minAge);
장점
- 불필요한 DTO 생성 없이 심플
단점
- 파라미터 수가 조금만 늘어나도 메서드 시그니처가 장황해짐
- 재사용/테스트 불리함
4. 보너스: 컬렉션(List·배열) 넘기기
List<Integer> ids = List.of(1, 3, 5);
List<User> users = userMapper.findByIds(ids);
<select id="findByIds" parameterType="list" resultType="com.example.User">
SELECT *
FROM users
WHERE id IN
<foreach collection="list"
item="id"
separator=","
open="("
close=")">
#{id}
</foreach>
</select>
5. 정리: 언제 무엇을 쓸까?
상황 | 추천 방식 | 비고 |
---|---|---|
대부분의 CRUD | 객체 | 타입 안전 & 유지보수 용이 |
동적 조건 or 칼럼이 바뀔 때 | Map | 빠른 프로토타이핑·Ad‑hoc 쿼리 |
단일 값(키 조회 등) | 프리미티브 | 성능·단순성 |
2~3개의 단순 조건 | 프리미티브 + @Param |
DTO 만들려니 애매할 때 |
IN 절 배치 조회 | 컬렉션(List/배열) | <foreach> 필수 |
6. 참고 자료
- opens.kr — 「MyBatis parameterType 정리」
- MyBatis 공식 문서: User Guide → Parameters
반응형