[Spring Boot] 57. 스프링부트 블로그 v3 (RestAPI) (2) Optional

김주희's avatar
May 06, 2025
[Spring Boot] 57. 스프링부트 블로그 v3 (RestAPI) (2) Optional
package shop.mtcoding.blog.temp; /* Optional.of(value) 절대 null이 아니어야 함 Optional.ofNullable(value) null일 수도 있음 Optional.empty() 빈 Optional 생성 get() 값 꺼냄 (값이 없으면 예외 발생) orElse(default) 값이 없으면 기본값 리턴 orElseGet(Supplier) 값이 없으면 람다 결과 리턴 orElseThrow() 값이 없으면 예외 발생 isPresent() 값이 있는지 확인 ifPresent(Consumer) 값이 있으면 처리 filter(Predicate) 조건에 맞는 값만 유지 */ public class OptionalTest { }
 
@Test public void t1(){ String name = "metacoding"; Optional<String> opt = Optional.of(name); System.out.println(opt.get()); }
notion image
 
 
@Test public void t1(){ String name = null; Optional<String> opt = Optional.of(name); System.out.println(opt.get()); }
notion image
Optional = 선물박스 (js의 promise도 선물박스
 
null을 처리하는 선물박스
장점
→ 내가 만약에 누구에게 요청했는데 null을 주면 null.~을 쓰면 nullPointException 터짐
선물 박스.~로 쓰게되니까 박스는 존재하므로 nullPointException이 안터짐 null 안정성을 제공
→ null이 들어올지 안들어올지 개념이 안잡히는 복잡한 경우 if로 처리 못하게
 
@Test public void t1(){ String name = null; Optional<String> opt = Optional.ofNullable(name); System.out.println(opt.get()); }
notion image
선물박스에서 꺼내니까 null 발생
 
 
@Test public void t1(){ String name = null; Optional<String> opt = Optional.ofNullable(name); if(opt.isPresent()){ System.out.println(opt.get()); }else{ System.out.println("선물박스에 값이 없어요."); } }
notion image
 
존재하면 if-else로 처리하겠다는 것
@Test public void t1(){ String name = "metacoding"; Optional<String> opt = Optional.ofNullable(name); if(opt.isPresent()){ System.out.println(opt.get()); }else{ System.out.println("선물박스에 값이 없어요."); } }
notion image
 
 
💡
만든 사람과 쓰는 사람이 동일x 경우 null 처리를 안하게 돼서 터진다 → optional 사용의 이유
 
 
optional 박스에 있는거 꺼내보기
get은 있든 없든 강제로 꺼냄
 
orElseThrow 이걸 제일 많이 쓴다.
 
throw 생략 가능
값이 없으면 throw를 터트리고
@Test public void t2(){ String name = "metacoding"; Optional<String> opt = Optional.ofNullable(name); String result = opt.orElseThrow(() -> new RuntimeException("값이 없어요.")); System.out.println(result); }
notion image
 
null이면 없으니까 밑의 sout이 실행안되고 throw가 터짐
@Test public void t2(){ String name = null; Optional<String> opt = Optional.ofNullable(name); String result = opt.orElseThrow(() -> new RuntimeException("값이 없어요.")); System.out.println(result); }
notion image
 
 
orElseGet : 없으면 터트리는게 아니라 디폴트 값이 존재할 수 있고 값이 없으면 디폴트 값이 나옴
→ 값이없더라도프로그램이 진행되어야 하고 뭐라도 값을 줘야 하는 경우?
notion image
@Test public void t3(){ String name = null; Optional<String> opt = Optional.ofNullable(name); String result = opt.orElseGet(() -> "metacoding"); System.out.println(result); }
notion image
 
 
게시글 5번을 조회하는데 db에 없으면 throw를 터트림
예시 - 호텔 예약시 할인 쿠폰을 서버한테 받으면 누구는 null/ 누구는 잇음 → 있으면 할인해서 처리해주면 됨/ 할인쿠폰null이면 default 값 0으로 바꿔서 처리
 
원래 코드
notion image
null일 수도 있다고 알려줘야 됨
notion image
 
Optional<User> userOP : Optional 객체임을 티를 낸다.
 
원래 코드
notion image
optional 처리
notion image
 
 
notion image
 
 
💡
실습) null 처리를 전부 Optional로 바꿔보자! (select)
 
repo 쪽에서 Optional을 return하면 null이 있을 수도 있겟구나! Optional 을 return하지 않을 경우 null이 무조건 없겟구나 하게 됨
 
 

풀이
 
 
public Board findByIdJoinUserAndReplies(Integer id) { Query query = em.createQuery("select b from Board b join fetch b.user left join fetch b.replies r left join fetch r.user where b.id = :id order by r.id desc", Board.class); query.setParameter("id", id); return (Board) query.getSingleResult(); }
→ 무조건 터질 수 있음
Optional 처리하면
 
public Board findByIdJoinUser(Integer id) { Query query = em.createQuery("select b from Board b join fetch b.user where b.id = :id", Board.class); query.setParameter("id", id); return (Board) query.getSingleResult(); }
→ 당연히 null일 수 있음
Optional 처리하면
 
💡
터지는지 null이 return 되는지 확인 → ctrl+space? OR JUnit Test 해보면 됨 실행도 해보고 디버깅해볼 수 있어ㅑ 됨
 
 
totalCount → 문제 생길 일 X 없으면 0이 나옴
findAll → getResultList()는 빈 배열을 리턴해줌 = 배열 자체가 0건인 걸 return해줌 ⇒ resultList는 null 처리 필요 없음
 
Q.Exception 터지는게 뭐가 문제야?
Exception이 터지면 콘솔이 계속 찍히기 때문에 IO가 계속 발생 → 서버가 느려짐
 
Share article

jay0628