728x90

뭐 제목은 거창하지만 내용은 별거 없을것 같다. 어로그 끌어서 미안하지만 …

일단 설명을 하자면 NPE를 방지하기 위한 노력은 예전부터 많은 JAVA 개발자들이 세세대대 이어져왔다.

아직도 개발도중에 NPE 은 우리를 항상 괴롭히기도 한다.

뭐 아시다싶이 apache Commons Utils 를 이용하여 String , Object 에 대한 null 체크를 대부분은 하고 있다. 하지만 오늘 얘기할 부분은 Optional 클래스에 위임하는 방식이니 이해하고 그냥 읽어만 달라.

가끈 팀프로젝트에서 해당 클래스를 이용해서 null 체크하라는 지시가 있을때 하려고하면 항상 까먹곤 하니 오늘 좀 자주쓰는 부분을 적어보자.

public OrderDto getOrderDto(Long orderId) {
    QOrder order = QOrder.order;
    QUser user = QUser.user;
    QItem item = QItem.item;

    OrderDto orderDto = queryFactory
        .select(Projections.constructor(OrderDto.class, order, user))
        .from(order)
        .leftJoin(order.user, user)
        .where(order.id.eq(orderId))
        .fetchOne();

    if (orderDto == null) {
        throw new NotFoundException("Order not found");
    }

    List<OrderItemDto> orderItemDtos = queryFactory
        .select(Projections.constructor(OrderItemDto.class, item))
        .from(orderItem)
        .join(orderItem.item, item)
        .where(orderItem.order.id.eq(orderId))
        .fetch();

    orderDto.setOrderItemDtos(orderItemDtos);

    return orderDto;
}

아래와 같이 개선 해보았다.

public OrderDto getOrderDto(Long orderId) {
    QOrder order = QOrder.order;
    QUser user = QUser.user;
    QItem item = QItem.item;

    OrderDto orderDto = queryFactory
        .select(Projections.constructor(OrderDto.class, order, user))
        .from(order)
        .leftJoin(order.user, user)
        .where(order.id.eq(orderId))
        .fetchOneOptional()
        .orElseThrow(() -> new NotFoundException("Order not found"));

    List<OrderItemDto> orderItemDtos = queryFactory
        .select(Projections.constructor(OrderItemDto.class, item))
        .from(orderItem)
        .join(orderItem.item, item)
        .where(orderItem.order.id.eq(orderId))
        .fetch();

    orderDto.setOrderItemDtos(orderItemDtos);

    return orderDto;
}

내저장소 바로가기 luxury515

'Back-end > 기타' 카테고리의 다른 글

gradle bootrun 작동 에러  (0) 2023.04.14
radius(레이디스)서버  (0) 2023.04.14
tomcat m1 설정  (0) 2023.04.13
IPv6 와 IPv4 를 비교했을때 장점은 뭐지?  (0) 2023.04.13
equals()와 hashCode() 에 대한 고찰  (0) 2023.04.13
728x90

ispresent vs ifpresent 의 차이점

Optional<OrderDto> optionalOrderDto = queryFactory
        .select(Projections.constructor(OrderDto.class, order, user))
        .from(order)
        .leftJoin(order.user, user)
        .where(order.id.eq(orderId))
        .fetchOneOptional();

if (optionalOrderDto.isPresent()) {
    OrderDto orderDto = optionalOrderDto.get();

    List<OrderItemDto> orderItemDtos = queryFactory
        .select(Projections.constructor(OrderItemDto.class, item))
        .from(orderItem)
        .join(orderItem.item, item)
        .where(orderItem.order.id.eq(orderId))
        .fetch();

    orderDto.setOrderItemDtos(orderItemDtos);

    return orderDto;
} else {
    throw new NotFoundException("Order not found");
}

위 코드에서는 isPresent() 메서드를 사용하여 Optional 객체가 null인지 체크하고, get() 메서드를 사용하여 OrderDto 객체를 가져옵니다. OrderDto 객체가 null이 아니면 해당 객체를 사용하여 쿼리를 실행하고, null이면 NotFoundException 예외를 발생시킵니다.

반면에 ifPresent()를 사용하면 다음과 같이 null 체크와 쿼리 실행을 한 번에 할 수 있습니다.

queryFactory
        .select(Projections.constructor(OrderDto.class, order, user))
        .from(order)
        .leftJoin(order.user, user)
        .where(order.id.eq(orderId))
        .fetchOneOptional()
        .ifPresent(orderDto -> {
            List<OrderItemDto> orderItemDtos = queryFactory
                    .select(Projections.constructor(OrderItemDto.class, item))
                    .from(orderItem)
                    .join(orderItem.item, item)
                    .where(orderItem.order.id.eq(orderId))
                    .fetch();

            orderDto.setOrderItemDtos(orderItemDtos);
        })
        .orElseThrow(() -> new NotFoundException("Order not found"));

위 코드에서는 ifPresent() 메서드를 사용하여 Optional 객체가 null이 아닐 때만 람다식을 실행하고, orElseThrow() 메서드를 사용하여 NotFoundException 예외를 발생시킵니다.

isPresent()ifPresent() 모두 null 체크를 수행하지만, ifPresent()는 null 체크와 쿼리 실행을 한 번에 처리할 수 있습니다. 그러나 ifPresent()는 리턴값을 갖지 않기 때문에, 리턴값을 사용해야 하는 경우에는 isPresent()get() 메서드를 사용해야 합니다.


내저장소 바로가기 luxury515

728x90
orElseorElseGet의 차이점은 메서드가 실행되는 시점입니다.
String email = userRepository.findById(id)
        .map(User::getEmail)
        .orElse("Unknown");
위 코드에서는 orElse를 사용하여 "Unknown"을 반환하도록 설정하였습니다. 만약 orElseGet 을 사용한다면 아래와 같이 작성할 수 있습니다.
String email = userRepository.findById(id)
        .map(User::getEmail)
        .orElseGet(() -> {
            logger.warn("User email is not found. Returning default email.");
            return "unknown@example.com";
        });
위 코드에서는 orElseGet 을 사용하여, Optional 객체가 비어있을 경우에만 로그를 출력하고, "unknown@example.com "을 반환하도록 설정하였습니다.


내저장소 바로가기 luxury515

+ Recent posts