본 캠프_50일차

졸용·2025년 4월 28일

TIL

목록 보기
51/144

(4월28일)

✏️ 향상된 for문 사용 시

Service 클래스에서 주문 목록 조회 위한 메서드

  1. storeId로 가게를 찾고
  2. 가게에 속한 주문들을 찾고
  3. 주문 하나하나를 OrderResponseDto로 변환해서
  4. 리스트에 담고
  5. 리스트를 반환하는 메서드
  • DTO를 만드는 이유는 엔티티(Entity) 를 직접 외부에 노출하면 위험하기 때문이야. (보안/유지보수 때문)
@Transactional
public List<OrderResponseDto> getOrderList(Long storeId) {
    Store store = entityFetcher.getStoreOrThrow(storeId);

    List<Order> orderList = orderRepository.findAllByStore(store);

    List<OrderResponseDto> orderResponseDtoList = new ArrayList<>();

    for (Order order : orderList) {
        OrderResponseDto orderResponseDto = new OrderResponseDto(order);
        orderResponseDtoList.add(orderResponseDto);
    }
    return orderResponseDtoList;
}

1. @Transactional

  • 이 메서드는 트랜잭션 안에서 실행된다는 뜻

  • 데이터베이스 작업(조회/수정 등)을 하나의 묶음으로 처리할 때 사용

  • 여기서는 조회만 하니까, 엄밀히 말하면 @Transactional(readOnly = true)를 붙이면 더 최적화된다


2. public List<OrderResponseDto> getOrderList(Long storeId) {

  • public:
    → 다른 클래스에서도 이 메서드를 자유롭게 호출할 수 있게 함

  • List<OrderResponseDto>:
    → 이 메서드가 반환(return) 하는 값은
    OrderResponseDto 객체들의 리스트(목록) 라는 뜻

  • getOrderList(Long storeId):
    → 메서드 이름은 getOrderList고,
    Long 타입의 storeId매개변수(parameter) 로 받음


3. Store store = entityFetcher.getStoreOrThrow(storeId);

  • storeId를 가지고, Store 객체를 하나 가져온다

  • 만약 storeId에 해당하는 가게가 없으면 예외를 던진다(throw)


4. List<Order> orderList = orderRepository.findAllByStore(store);

  • 방금 가져온 Store에 해당하는 모든 주문(Order) 들을 데이터베이스에서 가져온다

  • 그래서 orderList 안에는 Order 객체들이 쭉 여러 개 담긴다


5. List<OrderResponseDto> orderResponseDtoList = new ArrayList<>();

  • 이제 결과를 담을 빈 리스트(empty list) 하나 만든다

  • 타입은 OrderResponseDto들의 리스트

  • 처음에는 아무것도 안 들어있음


6. for (Order order : orderList) { ... }

  • 향상된 for문(Enhanced For Loop) 이다

  • orderList 안에 있는 각 Order 객체를 하나씩 꺼내서
    order라는 이름으로 사용하겠다는 뜻

예를 들면:

orderList = [OrderA, OrderB, OrderC]

첫 번째 반복: order = OrderA
두 번째 반복: order = OrderB
세 번째 반복: order = OrderC

즉, orderList에 있는 주문들을 하나하나 다루는 것


7. OrderResponseDto orderResponseDto = new OrderResponseDto(order);

  • Order 객체 하나를

  • OrderResponseDto라는 DTO 객체로 변환한다

DTO
"Data Transfer Object" — 즉,
데이터를 주고받을 때 필요한 형식으로 만든 객체를 말한다
(프론트엔드나 다른 서비스에 넘길 때 쓸 모델)


8. orderResponseDtoList.add(orderResponseDto);

  • 새로 만든 OrderResponseDto

  • 아까 만든 orderResponseDtoList에 추가(add)한다

반복될 때마다
orderResponseDto가 하나씩 리스트에 쌓인다


9. return orderResponseDtoList;

  • 마지막으로, 모든 변환이 끝난 OrderResponseDto 리스트를

  • 결과값으로 반환(return) 한다



✏️ stream 사용 시

@Transactional(readOnly = true)
public List<OrderResponseDto> getOrderList(Long storeId) {
    Store store = entityFetcher.getStoreOrThrow(storeId);

    List<Order> orderList = orderRepository.findAllByStore(store);

    List<OrderResponseDto> orderResponseDtoList = orderList.stream()
        .map(order -> new OrderResponseDto(order))
        .collect(Collectors.toList());

    return orderResponseDtoList;
}

4번까지 동일


5. orderList.stream()

  • orderList스트림(Stream) 으로 변환

  • 스트림은 "데이터의 흐름"을 만들어서 데이터를 하나하나 다루는 파이프라인처럼 동작한다

orderList = [OrderA, OrderB, OrderC]

stream()을 호출하면
OrderA → OrderB → OrderC 하나씩 처리할 수 있는 흐름(Stream)이 만들어진다

6. .map(order -> new OrderResponseDto(order))

  • 스트림 안의 Order 하나를 꺼내서

  • OrderResponseDto변환하는 작업을 정의하는 것

map은:
"무언가를 받아서 다른 무언가로 변환" 하는 역할을 한다

예시로 보면:

OrderA → OrderResponseDtoA
OrderB → OrderResponseDtoB
OrderC → OrderResponseDtoC

이렇게 각각 변환된다

  • order -> new OrderResponseDto(order)
    → 이건 람다식(lambda expression) 이라고 부르는데,
    간단하게 말하면
    "order를 받아서 new OrderResponseDto(order)를 반환하라"는 뜻이다

7. .collect(Collectors.toList())

  • 변환된 OrderResponseDto들을 하나하나 다시 리스트(List) 로 모은다

collect는:
"스트림 작업이 끝나면 결과를 모아서 담아라"는 뜻

  • Collectors.toList()는 스트림으로 흘러간 결과를
    새로운 ArrayList로 만들어 준다

8. List<OrderResponseDto> orderResponseDtoList = ...

  • 이렇게 만들어진 List<OrderResponseDto>를 변수에 저장한다

9. return orderResponseDtoList;

  • 그리고 이 리스트를 반환(return)한다

📚 Stream 전체 흐름 요약

orderList를 Stream으로 → 각 Order를 OrderResponseDto로 변환(map) → 
변환한 것들을 모아서 List로 수집(collect) → 반환

✨ 다시 한눈에 정리

구분for문 방식Stream 방식
Order 하나씩 꺼내기for (Order order : orderList)orderList.stream()
변환 방법new OrderResponseDto(order).map(order -> new OrderResponseDto(order))
리스트에 추가하기orderResponseDtoList.add(orderResponseDto).collect(Collectors.toList())

🔥 스트림을 쓰는 이유?

  • 가독성: 코드가 짧고 깔끔해진다

  • 선언형 프로그래밍: "어떻게"가 아니라 "무엇을 할지"를 표현할 수 있다

  • 병렬처리(Parallel Stream) 도 쉽게 적용할 수 있다 (.parallelStream())


📋 Stream 방식 정리그림

List<Order> orderList
       ↓ stream()
Order 객체 하나하나 흐름 만들기
       ↓ map()
Order를 OrderResponseDto로 변환
       ↓ collect()
변환한 것들 리스트로 모으기
       ↓ return


✅ 결론

  • for문은 익숙하고 이해가 쉽다.

  • Stream은 간결하고 트렌디하다.

  • 성능은 거의 차이 없다. (아주 극한 상황 아니면)

profile
꾸준한 공부만이 답이다

0개의 댓글