http://localhost:8000/blog/dummy/user/page?page=0
일단 application.yml에서 ddl-auot를 update로 수정해서 테이블이 drop되는 것을 막는다.
findById
findById는 User 타입이 아닌 Optional 타입으로 return해준다. 만약 user/4를 찾을 예정인데 DB에서 못찾게 되면 user가 null이 될 것이다. 그럼 return할 때 null이 return될 텐데 이러면 프로그램 자체에 에러가 생긴다. 그래서 Optional로 user 객체를 감싸서 가져와서 null인지 판단 후 return하면 된다.
.get()
User user = userRepository.findById(id).get();
null이 절대 return될 일 없는 경우 .get()으로 user 객체를 바로 Optional에서 뽑아서 주는 것이다. 근데 절대 없는 경우는 있기 힘들다. 만약 회원가입을 3명이 해서 Id가 1, 2, 3만 존재할 때 user/5를 찾은 후 .get()을 해버리면 에러가 날 것이다. 따라서 .get()은 위험하다.
.orElseGet()
.orElseGet()은 Supplier 타입이 들어간다. Supplier은 인터페이스니까 new할 수 없기 때문에 new하려면 익명 객체를 생성해야 한다. 생성 후 인터페이스의 함수 get을 오버라이딩 해준다.
User user = userRepository.findById(id).orElseGet(new Supplier<User>() {
@Override
public User get() {
return new User();
}
});
정상적으로 Id로 User를 찾았다면 그대로 반환할 것이고, 그게 아니라면 빈 객체를 user에 넣어줘서 반환해준다.
.orElseThrow
User user = userRepository.findById(id).orElseThrow(new Supplier<IllegalArgumentException>() {
@Override
public IllegalArgumentException get() {
return new IllegalArgumentException("해당 유저는 없습니다. id: "+id);
}
});
가장 권장하는 방법으로 정상적으로 찾으면 그대로 반환하고, 그게 아니라면 에러 페이지를 낸다.
나중에는 스프링에서 AOP 기능을 통해 IllegalArgumentException와 같은 익셉션이 발생하면 가로채서 만들어둔 에러 페이지를 보여줄 것이다.
자바8의 람다식을 사용하면 더 간략하게 코딩할 수 있다.
User user = userRepository.findById(id).orElseThrow(()->{
return new IllegalArgumentException("해당 유저는 없습니다. id: "+id);
})
MessageConverter
지금 실습하고 있는 DummyControllerTest 클래스는 @RestController라서 html 파일이 아닌 데이터를 return해준다. 하지만 요청은 웹 브라우저에서 하고 있고 우리가 반환하는 데이터는 자바 오브젝트인 user 객체이기 때문에 웹 브라우저가 이해할 수 있는 JSON으로 변환해주어야 한다.
스프링부트는 MessageConverter라는 애를 응답시에 자동 작동시켜서 자바 오브젝트를 return하게 되면 Jackson이라는 라이브러리를 호출해서 user 오브젝트를 JSON으로 변환 후 브라우저에게 보내준다.
전체 select 테스트
// 전체를 다 받을 거라서 특별히 파라미터를 받을 필요가 없다.
// http://localhost:8000/blog/dummy/users
@GetMapping("/dummy/users")
public List<User> list() {
return userRepository.findAll();
}
paging 테스트
한 페이지당 2건의 데이터를 리턴받고 싶을 때에는 JPA의 강력한 기술인 findAll의 pagealbe을 이용한다. findAll의 pagealbe 기능은 Page를 리턴해준다.
Page<T> findAll(Pageable pageable);
한 페이지당 2건의 데이터(size = 2), id 기준 정렬(sort = "id"), id 최신순 정렬(direction = Sort.Direction.DESC)
// 한 페이지당 2건의 데이터 리턴 - paging
// http://localhost:8000/blog/dummy/user
@GetMapping("/dummy/user")
public Page<User> pageList(@PageableDefault(size = 2, sort ="id", direction = Sort.Direction.DESC) Pageable pageable) {
// findAll의 pagealbe 기능은 Page를 리턴해준다.
Page<User> users = userRepository.findAll(pageable);
return users;
}
현재 id가 1, 2, 3으로 3개가 있으니까 최신 순으로 2개씩 페이지화될 것이다.
http://localhost:8000/blog/dummy/user?page=0 접속시 id 3, 2 출력 - 첫 페이지라서 ?page=0 생략 가능
http://localhost:8000/blog/dummy/user?page=1 접속시 id 1 출력
그런데 Page 타입으로 return하니까 부수적인 것들이 많이 출력된다. 이를 없애기 위해 .getContent()를 해줘서 List 타입으로 바꾼 후 반환해주자
@GetMapping("/dummy/user")
public List<User> pageList(@PageableDefault(size = 2, sort ="id", direction = Sort.Direction.DESC) Pageable pageable) {
List<User> users = userRepository.findAll(pageable).getContent();
return users;
}
더 좋은 방법으로는 그대로 Page 타입으로 하고 users를 따로 빼서 반환해주는 것이다. 이렇게 하면 Page의 다른 부가 기능을 사용할 수 있어서 좋다.
@GetMapping("/dummy/user")
public List<User> pageList(@PageableDefault(size = 2, sort ="id", direction = Sort.Direction.DESC) Pageable pageable) {
Page<User> pagingUser = userRepository.findAll(pageable);
List<User> users = pagingUser.getContent();
return users;
}
출처 : https://www.youtube.com/c/%EB%A9%94%ED%83%80%EC%BD%94%EB%94%A9
'Spring > Blog 만들기 with SpringBoot' 카테고리의 다른 글
delete 테스트, Exception 처리 (0) | 2022.05.16 |
---|---|
update 테스트, JPA 영속성 컨텍스트 (0) | 2022.05.16 |
insert 테스트, enum 사용법 (0) | 2022.05.10 |
JSON (0) | 2022.05.10 |
연관관계의 주인 (0) | 2022.05.08 |