Service - 책 한건보기, 책 삭제 및 수정

jihan kong·2022년 9월 13일
0

JUnit5

목록 보기
13/25
post-thumbnail

본 시리즈는 메타 코딩님의 Junit 강의를 학습한 내용을 바탕으로 정리하였습니다.

Service layer에서 지금까지 책 목록보기와 책 등록. 즉, CreateRead 를 구현했다. 이제 Read 의 또 다른 기능인 책 한건보기를 구현하고 나머지 삭제와 수정을 모두 한번에 구현할 것이다.

책 한건보기

BookService.java

	// 1. 책 등록하기
    public BookRespDto 책등록하기(BookSaveReqDto dto) {
  		// (...생략)
    }
    
    // 2. 책 목록보기
	public List<BookRespDto> 책목록보기() {
		// (...생략)
    }
    
    // 3. 책 한건보기
    public BookRespDto 책한건보기(Long id) {
        Optional<Book> bookOP = bookRepository.findById(id);
        if(bookOP.isPresent()) {  //찾았다면
            return new BookRespDto().toDto(bookOP.get());
        } else {
                throw new RuntimeException("해당 아이디를 찾을 수 없습니다.");
            }       
        }

책 한건보기는 쉽게 구현할 수 있다. Java8의 Optional 클래스를 통해 bookRepository 에서의 null 값을 허용시키고, 만약 찾았다면 Dto 에서 get으로 리턴. 못 찾았다면 RuntimeException 을 터뜨려주면 된다.

Optional 클래스 정확히 어떤 것일까?
저의 블로그 시리즈 중 spring 입문 강의를 들으면서 정리한 포스팅을 참고해주세요...! 😀
https://velog.io/@kjh950330/TIL-JAVA-spring-DAY-6


책 삭제하기

BookService.java

	// 1. 책 등록하기
    public BookRespDto 책등록하기(BookSaveReqDto dto) {
  		// (...생략)
    }
    
    // 2. 책 목록보기
	public List<BookRespDto> 책목록보기() {
		// (...생략)
    }
    
    // 3. 책 한건보기
    public BookRespDto 책한건보기(Long id) {
		// (...생략)     
    }
    
    // 4. 책 삭제하기
    @Transactional(rollbackOn = RuntimeException.class)
    public void 책삭제하기(Long id) {    
        bookRepository.deleteById(id); 
    }
    

책 삭제하기도 마찬가지로 위와 같이 간단하게 구현할 수 있다.
그런데 한 가지 의문점이 있다.

BookRepository 는 ID를 통해서 삭제하는 구조이다. 테이블에 record ID가 1, 2, 3 까지만 들어와있다고 가정하자. 그런데 ID가 4 인 record를 삭제하려고 한다면 즉, 쿼리문으로 delete from book where id = 4; 를 실행한다면 오류가 발생하게 될까?

정답은 "오류가 발생하지 않는다." 이다. DB에서 찾지 못했다고 해서 오류가 발생하는 것은 아니다. Null이면 당연히 IllegalArgumentException 이 터지겠지만 4 의 경우는 DB에 없는 번호일 뿐, Null은 아닌 것이다. 사실 이 경우에는 DB쪽에서 삭제도 되지 않았기 때문에 Rollback 또한 되지 않았을 것이다.

마지막으로 책 수정하기를 살펴보자.

책 수정하기

BookService.java

	// 1. 책 등록하기
    public BookRespDto 책등록하기(BookSaveReqDto dto) {
  		// (...생략)
    }
    
    // 2. 책 목록보기
	public List<BookRespDto> 책목록보기() {
		// (...생략)
    }
    
    // 3. 책 한건보기
    public BookRespDto 책한건보기(Long id) {
		// (...생략)     
    }
    
    // 4. 책 삭제하기
    @Transactional(rollbackOn = RuntimeException.class)
    public void 책삭제하기(Long id) {    
		// (...생략)
    }
    
    // 5. 책 수정하기
    @Transactional(rollbackOn = RuntimeException.class)
    public void 책수정하기(Long id, BookSaveReqDto dto) {    // id, title, author
        Optional<Book> bookOP = bookRepository.findById(id); // 1, 2, 3
        if(bookOP.isPresent()) {
            Book bookPS = bookOP.get();
            bookPS.update(dto.getTitle(), dto.getAuthor());
        }else {
            throw new RuntimeException("해당 아이디를 찾을 수 없습니다.");
        }
    }   
    

책을 수정하기 위해서는 인자로 id, title, author 를 모두 받아야 한다. id 를 통해 책이 실제로 있는지 찾고, titleauthor 를 수정할 것이기 때문이다. 그런데 titleauthorBookSaveDto 로 구현해놓았기 때문에 BookSaveDto 를 가져다 쓴다.

책 수정도 책 한건보기와 마찬가지로 책을 찾았을 때와 못 찾았을 때로 나누어서 생각한다. 책을 찾았을 경우, 영속화된 bookPS 객체에 실제로 업데이트를 진행하면 된다. 이렇게 한다면 메서드가 종료될 때, 더티체킹으로 업데이트가 실행된다. 즉, DB쪽으로 flush가 되고 커밋이 되는 것이다.
반면, 못 찾았을 경우, RuntimeException 을 터뜨려 주면 된다.


🎉 Service layer 구현 완료 🎉

마침내.. 드디어 Service layer의 모든 구현이 끝났다!
이제 이 코드들이 잘 동작하는지 테스트코드를 다음 포스트에서 구현해보자.

profile
학습하며 도전하는 것을 즐기는 개발자

0개의 댓글