웹 개발/개념 정리

resultType= DTO / MAP 차이

cha430 2025. 6. 17. 11:05

 

MyBatis 쓰다보면

헷갈리는 parameterType과 resultType ... 정리 ..

 

 

MyBatis는 매퍼에서 전달되는 파라미터가 하나일 때는 명확하게 인식할 수 있지만

두 개 이상일 때는 어떤 이름으로 어떤 타입이 오는지 알 수 없다.

 

그래서 내부적으로 Map으로 wrapping한다.

 

@Param 어노테이션을 사용하면 내부적으로 "key = 파라미터 이름, value = 값" 형태로

Map<String, Object>로 변환된다.

 

Controller.java

public ArrayList<MainDto.Item> searchAssetsWithPaging(
    @Param("kwd") String kwd,
    @Param("startDate") LocalDate startDate,
    @Param("endDate") LocalDate endDate,
);

 

 

이 값들을 mapper.xml 에서 #{kwd}, #{startDate} 처럼 쓰면 된다.

 

<select id="searchAssetsWithPaging" parameterType="map" resultType="your.package.MainDto$Item">
    SELECT * 
    FROM tbl_asset
    WHERE 조건

 

parameterType="map" : 여러 파라미터들이 @param 어노테이션 때문에 Map으로 들어가기 때문

 

 

 

 


 

 

  DTO MAP
가독성 👍 명확한 필드 이름, 타입 지정 👎 어떤 key가 있는지 명확하지 않음
유지보수 👍 리팩토링, IDE 자동완성 등 지원 👎 key 이름이 바뀌면 전부 수동 수정 필요
속도 거의 차이 없음 (Map은 약간 더 유연함) 유연하지만, 타입 캐스팅 필요
추천 사용 시점 - 데이터 구조가 정해져 있을 때
- 팀 협업 시 명확성 중요할 때
- 동적 쿼리 결과가 다를 때
- 컬럼 수가 가변적일 때

 

<DTO>
List<AssetDto> assets = assetMapper.getAssets();
System.out.println(assets.get(0).getAssetName());


<MAP>
List<Map<String, Object>> assets = assetMapper.getAssetsAsMap();
System.out.println(assets.get(0).get("asset_name"));

 

Map은 key값 오타 주의해야 한다.

 

 

 


 

연습해보자..

 

@PostMapping("/searchPaging.do")
public ResponseEntity<MainDto> getAssetsPaging(
    @RequestParam(value = "kwd", required = false) String kwd,
    @RequestParam(value = "page", defaultValue = "1") int page,
    @RequestParam(value = "pageLength", defaultValue = "20") int pageLength,
    @RequestParam(value = "startDate", required = false) @DateTimeFormat(...) LocalDate startDate,
    @RequestParam(value = "endDate", required = false) @DateTimeFormat(...) LocalDate endDate
) {

 

Controller에서 @RequestParam 으로 각각 받았어

Map<String, Object> paramMap = new HashMap<>();
paramMap.put("kwd", kwd);
paramMap.put("startDate", startDate);
paramMap.put("endDate", endDate);
paramMap.put("limit", pageLength);
paramMap.put("offset", (page - 1) * pageLength);

List<MainDto.Item> items = assetMapper.searchAssetsWithPaging(paramMap);

 

그럼 Service에서 Map에 담아서 넘겨야 한다

 

List<MainDto.Item> searchAssetsWithPaging(Map<String, Object> params);

 

Mapper도 파라미터를 Map에 담아서 넘겨야 한다.

 

SELECT ...
FROM tbl_asset
<include refid="searchCondition"/>
ORDER BY acq_date DESC
LIMIT #{limit} OFFSET #{offset}

 

내부적으로 MyBatis가 

#{limit} → paramMap.get("limit"), #{kwd} → paramMap.get("kwd") 이렇게 인식