본문 바로가기
프로젝트/도서관리 프로젝트

도서관리 프로젝트[8] 책 대출 기능 만들기

by CodeMango 2023. 6. 25.

 

 

APi스펙

 

1.  테이블 만들기

 

is_return 은 반납여부

 

2. UserLoanHistory 객체 만들기

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

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class UserLoanHistory {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id = null;
    private long userId;
    private String bookName;
    private boolean isReturn; //0이면 false, 1이면 true로 생각!


    protected UserLoanHistory() {

    }
    public UserLoanHistory(Long id, String bookName) {
        this.id = id;
        this.bookName = bookName;
        this.isReturn = false;
    }

}

 

3. UserLoanHistoryRepository 만들기

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

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserLoanHistoryRepository extends JpaRepository<UserLoanHistory, Long> {

    //select * from user_loan history where book_name =? and is_return = ?
    boolean existsByBookNameAndIsReturn(String name, boolean isReturn);
}

 

4. dto만들기

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

public class BookLoanRequest {

    private String userName;
    private String bookName;

    public String getUserName() {
        return userName;
    }

    public String getBookName() {
        return bookName;
    }
}

 

5. controller 에     @PostMapping("/book/loan") 추가

package com.group.libraryapp.controller.book;

import com.group.libraryapp.dto.book.request.BookCreateRequest;
import com.group.libraryapp.service.book.BookService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class BookController {

    private final BookService bookService;

    //생성자 만들어서 스프링빈 주입받기
    public BookController(BookService bookService) {
        this.bookService = bookService;
    }

    @PostMapping("/book")
    public void saveBook(@RequestBody BookCreateRequest request) {
        bookService.saveBook(request);
    }

    @PostMapping("/book/loan")
    public void loanBook(@RequestBody BookLoanRequest request){
        bookService.loanBook(request);
    }
}

6.  BookRepository에 findByName메소드 추가

package com.group.libraryapp.domain.book;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface BookRepository extends JpaRepository<Book, Long> {

    Optional<Book> findByName(String name);

}

7. Book 에 getter추가

package com.group.libraryapp.domain.book;

import javax.persistence.*;

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id = null;

    @Column(nullable = false, length = 255, name = "name")
    private String name;

    protected Book(){

    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    //id는 자동 생성이니까 이름 받는 생성자만 만듬
    public Book(String name) {
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException(String.format("잘못된 name(%s)이 들어왔습니다", name));
        }
        this.name = name;
    }
}

8. service에 loanBook 추가

package com.group.libraryapp.service.book;

import com.group.libraryapp.domain.book.Book;
import com.group.libraryapp.domain.book.BookRepository;
import com.group.libraryapp.domain.user.User;
import com.group.libraryapp.domain.user.UserRepository;
import com.group.libraryapp.domain.user.loanhistory.UserLoanHistory;
import com.group.libraryapp.domain.user.loanhistory.UserLoanHistoryRepository;
import com.group.libraryapp.dto.book.request.BookCreateRequest;
import com.group.libraryapp.dto.book.request.BookLoanRequest;
import net.bytebuddy.pool.TypePool;
import org.springframework.stereotype.Service;


import javax.transaction.Transactional;

@Service
public class BookService {

    private final BookRepository bookRepository;
    private final UserLoanHistoryRepository userLoanHistoryRepository;
    private final UserRepository userRepository;

    //생성자를 통해 레포지토리 주입받기
    public BookService(BookRepository bookRepository, UserLoanHistoryRepository userLoanHistoryRepository, UserRepository userRepository) {
        this.bookRepository = bookRepository;
        this.userLoanHistoryRepository = userLoanHistoryRepository;
        this.userRepository = userRepository;
    }

    @Transactional
    public void saveBook(BookCreateRequest request){
        bookRepository.save(new Book(request.getName()));
    }

//    @Transactional
    public void loanBook(BookLoanRequest request){
        //1. 책 정보 가져오기(이름 기준으로) -> 책이 있다면 책 객체가 book으로 들어옴


       Book book = bookRepository.findByName(request.getBookName())
                .orElseThrow(IllegalArgumentException::new);

        //2. 대출기록 정보 확인해서 대출중인지 확인하기
        //3. 만약 확인했는데 대출 중이라면 예외 발생시키기
       if(userLoanHistoryRepository.existsByBookNameAndIsReturn(book.getName(), false)) {
           throw new IllegalArgumentException("이미 대출되어 있는 책입니다");
       }

       //4. 유저 정보 가져오기
        User user = userRepository.findByName(request.getUserName());
              //  .orElseThrow(IllegalArgumentException::new);

        //5. 유저 정보와 책 정보를 기반으로 UserLoanHistory를 저장
        userLoanHistoryRepository.save(new UserLoanHistory(user.getId(), book.getName()));


    }
}

댓글