티스토리 뷰

Backend/Spring

#30 반납 기능

RadderNepa 2023. 10. 9. 18:31
[요구 사항]
- 사용자가 책을 반납할 수 있다.
[API 스펙]
- HTTP Method : PUT
- HTTP Path : /book/return
- HTTP Body(JSON) : {
     "userName" : String,
     "bookName" : String
}
- 결과 반환 X, HTTP Code 200이면 OK

- 대출(/book/loan)과 반납(/book/return)을 위한 HTTP Body(DTO)가 완전히 동일하다.

- 이때 반납을 위한 DTO를 새로 만드는게 좋을까? or 재활용하는게 좋을까?

cf) 대출을 위한 DTO(BookLoanRequest)는 이전 글에서 이미 만들어져 있는 상태

인프런 - 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지!(최태현)

- 이 경우 강사는 (개인적으로) 새로 만드는 것을 선호한다.

- why? 나중에 대출과 반납 중 한 기능에 변화가 생겼을 때 유연하게 대처할 수 있기 때문이다.


1. 반납을 위한 Table은 따로 만들 필요 없다.(user_loan_history table 그대로 사용)

2. BookRetuenRequest(DTO)

package com.group.libraryapp.dto.book.request;

public class BookRetuenRequest {
    private String bookName;
    private String userName;

    public String getBookName() {
        return bookName;
    }

    public String getUserName() {
        return userName;
    }
}

 

3. Controller, Service

Controller

@RestController
public class BookController {

    private final BookService bookService;

    @PutMapping("/book/return")
    public void returnBook(@RequestBody BookRetuenRequest request) {
        bookService.returnBook(request);
    }
}

 

Service

@Service
public class BookService {
    private final BookRepository bookRepository;
    private final UserLoanHistoryRepository userLoanHistoryRepository;
    private final UserRepository userRepository;

    // 생성자를 만들어 Spring bean을 주입받는다.
    public BookService(BookRepository bookRepository,
                       UserLoanHistoryRepository userLoanHistoryRepository,
                       UserRepository userRepository
    ) {
        this.bookRepository = bookRepository;
        this.userLoanHistoryRepository = userLoanHistoryRepository;
        this.userRepository = userRepository;
    }

    @Transactional
    public void returnBook(BookRetuenRequest request) {
        // 1. User table에서 User 정보를 가져온다.
        User user = userRepository.findByName(request.getUserName())
                .orElseThrow(IllegalArgumentException::new);

        // 2. 유저의 ID와 책 이름을 이용해 대출 기록을 가져온다.
        UserLoanHistory userLoanHistory = userLoanHistoryRepository
                .findByUserIdAndBookName(user.getId(), request.getBookName())
                .orElseThrow(IllegalArgumentException::new);
        
        // 3. 반납 처리
        userLoanHistory.doReturn();

        // 4. user_loan_history 테이블의 IS_RETURN 컬럼 업데이트
        // 영속성 컨텍스트의 '변경 감지' 기능으로 인해 별도의 코드나 쿼리를 작성할 필요가 없다.(그래서 아래 코드 주석 처리)
        // by @Transactional Annotation
        // userLoanHistoryRepository.save(userLoanHistory);
    }
}

- UserLoanHistory에 doReturn method 추가

package com.group.libraryapp.domain.user.loanhistory;

import javax.persistence.*;

@Entity
public class UserLoanHistory {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id = null;

    @Column(nullable = false, name = "user_id")
    private long userId;

    @Column(nullable = false, name = "book_name")
    private String bookName;

    @Column(nullable = false, name = "is_return")
    // is_return 컬럼은 자료형이 tinyint이기 때문에 DB에 0(false) 혹은 1(true)이 들어가도 된다.
    // == boolean으로 처리해도 tinyint에 잘 매핑된다.
    private boolean isReturn;

    protected UserLoanHistory() {}

    public UserLoanHistory(long userId, String bookName, boolean isReturn) {
        this.userId = userId;
        this.bookName = bookName;
        this.isReturn = isReturn;
    }

    public boolean getIsReturn() {
        return isReturn;
    }

    // 반납 처리
    public void doReturn() {
        this.isReturn = true;
    }
}

 

cf) userLoanHistoryRepository.save(userLoanHistory)를 주석 처리한 이유

2023.09.28 - [Spring] - #27 영속성 컨텍스트

 

#27 영속성 컨텍스트

- Service 계층의 주요 역할 중 하나가 트랜잭션을 관리하는 것이다. @Transactional - Spring에서 트랜잭션을 적용하는 방법 - 메소드에 @Transactional Annotation이 붙으면 메소드가 시작될 때 트랜잭션을 시

radderveloper.tistory.com


● 테스트

- user_loan_history table 현재 상황(0 = 대출 중 / 1 = 반납 완료)  /  user table 현재 상황

user_loan_history table  /  user table

[현재 대출 상황]
손승완 - 주먹을 단련하는 법
배주현 - 하체를 단련하는 법

반납 완료

'Backend > Spring' 카테고리의 다른 글

#29 대출 기능 API  (1) 2023.10.07
#28 책 생성 API - INSERT  (1) 2023.10.02
#27 영속성 컨텍스트  (1) 2023.09.28
#26 JPA를 이용해 SQL 날리기 with Spring Data JPA2  (0) 2023.09.26
#25 트랜잭션 - 이론  (0) 2023.09.25
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함