우선 User를 3개 만든다. id는 1, 2, 3 이다.
< DummyControllerTest >
Optional의 함수로는,
// {id} 주소로 파라미터를 전달 받을 수 있음
// http://localhost:8000/blog/dummy/user/3
@GetMapping("/dummy/user/{id}")
public User detail(@PathVariable int id) {
User user = userRepository.findById(id).get();
return user;
}
// {id} 주소로 파라미터를 전달 받을 수 있음
// http://localhost:8000/blog/dummy/user/3
@GetMapping("/dummy/user/{id}")
public User detail(@PathVariable int id) {
// findById의 리턴 값은 Optional임
// 그 이유는 -> user/4를 찾는데 만약 데이터베이스에서 못 찾아오게 되면 user가 null이 된다.
// 그러면 return null; 이 된다. 이렇게 되면 프로그램에 문제가 생겨서 Optional로 User 객체를 감싸서 가져올테니 null인지 아닌지 판단해서 리턴하라는 것이다.
// Optional의 함수 : [1] .get() - null이 리턴되지 않는다고 장담(?)할 때 사용, [2] .orElseGet() - 익명 객체 생성하기
// .orElseGet() -> 만약 id 값이 DB에 존재한다면 .orElseGet ~ return User(); 까지의 코드는 해당하지 않을 것이다. 빈 객체를 user에 넣으면 null은 아니기 때문에 사용한다.
User user = userRepository.findById(id).orElseGet(new Supplier<User>() {
@Override
public User get() {
return new User();
}
});
return user;
}
주소창에다가 http://localhost:8000/blog/dummy/user/3
을 치면 DB에 id=3인 User가 있으므로 정상적으로 해당 User의 데이터가 출력될 것이다. (Json 형식으로)
만약 없는 id를 select한다면?! -> http://localhost:8000/blog/dummy/user/100
을 하면 id=100은 DB에 없으므로 user는 null이 된다.
따라서 findById는 반환형을 Optional로 가지고 있는 함수이다.
User user = userRepository.findById(id);
이렇게만 하면 에러 난다. Optional이라서 타입을 User로 하면 안된다.
null이 되지 않도록, Optional로 User 객체를 감싼다.
// 다른 방법 !! [3] @throws IllegalArgumentException if {@literal id} is {@literal null}.
User user = userRepository.findById(id).orElseThrow(new Supplier<IllegalArgumentException>() {
@Override
public IllegalArgumentException get() {
return new IllegalArgumentException("해당 유저는 없습니다. id : " + id);
}
});
return user;
주소창에 http://localhost:8000/blog/dummy/user/100
을 하면,
이렇게 응답하게 된다.