본문 바로가기
Today I Learned 2024. 6. 20.

(24.06.20)[10주차] Optional 객체값 가져오기


Optional 객체

 User user = userRepository.findByUsername(username).orElseThrow(
                () -> new IllegalArgumentException("회원을 찾을 수 없습니다.")
        );
  • Controller - Service - Repository 형태의 3 Layer Architecture 에서 위 코드와 같은 쿼리 메서드를 레포지토리에 JpaRepository<> 를 extends 시켜서 사용할 수 있다.
  • 하지만, 여러  실습을 통해서 무조건 findBy로 찾지 못했을 때, orElseThrow 만 사용하는 것을 실습을 통해 많이 사용하지만, 예외가 던져진다면, 서버에서 작동을 멈추는 단점이 있기도 했다.
    • 이 때 만들어지는 쿼리 메서드는 작동하지만, 값이 없을 수 있을 때를 가정해서 항상 Optional<> 로 반환이 된다. 즉, Optional 객체처럼 취급하여 다룰 수 있다는 것으로 코드를 짜면선 생각을 했고, Optional 객체에 대해서 한번 정리하고, 적용할 수 있는지 정리했다.

Optional <T> 객체

  • 말그래도 알고있었던 T타입의 객체를 감싼 Wrapper 클래스이기 때문에 반환 결과가 null일 때를 대비해서 여러가지 작업을 할 수 있는 것
    • 따라서, stream의 중간연산 최종연산 모두 사용할 수 있음
  • NullPointerException 을 방지할 수 있음
    • 하지만, 그렇다고 해서 무조건 모든 예외가 발생하지 않을 순 없음

Optional<T> 객체 값 가져오기

  • Optional은 사실상 감싼 T타입 또는 null 이반환되어야하기 때문에 여러 객체 값을 가져오는데 다양하게 활용을 할 수 있고, 위의 JpaRepository의 쿼리메서드에도 사용이 될 수 있기 때문에 찾아보고 학습하면서 정리하고자 한다.

.get()

  • 그냥 객체 다 가져오기 단, null일경우 NullPointerException이 아닌, NoSuchElementException 던져질 수 있음

.orElse()

  • 가져올 객체가 없을 때 = Optional이 비어있을 때,  ()의 값 반환

.orElseGet()

User user = userRepository.findByUsername(username)
    .orElseGet(() -> {
        if (isAdminUser(username)) {
            return new AdminUser("admin");
        } else {
            return new User("user");
        }
    });
  • 대체 람다식 중 Supplier 함수형 인터페이스만 가능
    • 반환 값을 내놓는 람다식에 안해서 사용을 할 수 있고, 그 외의 return 값이 존재하는 로직을 써서 활용할 수도 있음

.orElseThrow()

  • () 안에 람다를 써서 특정 예외를 발생시킬 수 있음
    • 대체 예외 발생 = NullPointerException은 굳이 사용X
  • 맨 위의 코드

.isPresent()

  • Boolean 타입으로 출력, Optional 객체의 값이 null일경우 false, 아니면 true 반환
    • Opetional.ofNullable(str).isPresent();

.ifPresent()

userRepository.findByUsername(username)
    .ifPresent(user -> {
        System.out.println("사용자 이름: " + user.getUsername());
        System.out.println("사용자 이메일: " + user.getEmail());
        System.out.println("사용자 나이: " + user.getAge());
    });
  • Optional 객체의 값이 null이 아닐 때만 () 값 출력, 어차피 null 일 경우엔 아무일도 안일어나기 때문
    • Optional.ofNullable(str).ifPresent(System.out::println) 포맷으로도 사용할 수 있음
    • 서비스에서 작동되는 로직에 따라서 다양하게 확장시킬 수 있음
    • log.info 로 로깅을 할 수 있도록 확장이 가능