Today I Learned
(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 로 로깅을 할 수 있도록 확장이 가능
'Today I Learned' 카테고리의 다른 글
(24.06.25)[11주차] Spring Security의 User 권한 설정 (0) | 2024.06.25 |
---|---|
(24.06.21)[10주차] CrudRepository & Delete 쿼리 메서드 (0) | 2024.06.21 |
(24.06.19)[10주차] Mockito 구문 (0) | 2024.06.19 |
(24.06.18)[10주차] Reflection & ReflectionTestUtils을 통한 필드 다루기 (0) | 2024.06.18 |
(24.06.17)[10주차] Validator 객체 생성과 테스트 코드에서의 활용 (0) | 2024.06.17 |