김뱅쓰
2023. 8. 13. 20:08
섹션 4. 두 번째 요구사항 추가하기 - 도서 대출 현황
섹션 5. 세 번째 요구사항 추가하기 - 책 통계
https://www.inflearn.com/course/java-to-kotlin-2/dashboard
실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링) - 인프
Java + Spring Boot로 만들어진 웹 애플리케이션을 Kotlin + Spring Boot로 리팩토링 하고 추가 요구사항을 구현합니다. 이 과정에서 Junit5, SQL, JPA, Querydsl 을 사용할 뿐 아니라, 설계 및 구현 관점에서 다양
www.inflearn.com
repository (book)
package com.group.libraryapp.domain.book
import com.group.libraryapp.dto.book.response.BookStatResponse
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import java.util.Optional
interface BookRepository : JpaRepository<Book, Long>{
fun findByName(bookName: String): Book?
}
(user)
package com.group.libraryapp.domain.user
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import java.util.*
interface UserRepository: JpaRepository<User,Long>, UserRepositoryCustom{
fun findByName(name: String) : User?
}
book dto
request
package com.group.libraryapp.dto.book.request
data class BookLoanRequest(val userName: String, val bookName: String)
package com.group.libraryapp.dto.book.request
import com.group.libraryapp.domain.book.BookType
data class BookRequest(
val name: String,
val type: BookType,
)
package com.group.libraryapp.dto.book.request
data class BookReturnRequest(val userName: String, val bookName: String)
response
package com.group.libraryapp.dto.book.response
import com.group.libraryapp.domain.book.BookType
data class BookStatResponse(
val type: BookType,
val count: Long,
)
// {
// fun plusOne(){
// count++
// }
//}
bookservice
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.book.BookType
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.domain.user.loanhistory.UserLoanStatus
import com.group.libraryapp.dto.book.request.BookLoanRequest
import com.group.libraryapp.dto.book.request.BookRequest
import com.group.libraryapp.dto.book.request.BookReturnRequest
import com.group.libraryapp.dto.book.response.BookStatResponse
import com.group.libraryapp.repository.book.BookQuerydslRepository
import com.group.libraryapp.repository.user.loanhistory.UserLoanHistoryQuerydslRepository
import com.group.libraryapp.util.fail
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
@Service
class BookService(
private val bookRepository: BookRepository,
private val bookQuerydslRepository: BookQuerydslRepository,
private val userRepository: UserRepository,
private val userLoanHistoryQuerydslRepository: UserLoanHistoryQuerydslRepository,
) {
@Transactional
fun saveBook(request: BookRequest){
val newBook = Book(request.name,request.type)
bookRepository.save(newBook)
}
@Transactional
fun loanBook(request: BookLoanRequest){
val book = bookRepository.findByName(request.bookName)?: fail()
if (userLoanHistoryQuerydslRepository.find(request.bookName,UserLoanStatus.LOANED) != null){
throw IllegalArgumentException("진작 대출되어 있는 책입니다")
}
val user= userRepository.findByName(request.userName)?: fail()
user.loanBook(book)
}
@Transactional
fun returnBook(request: BookReturnRequest){
val user = userRepository.findByName(request.userName)?: fail()
user.returnBook(request.bookName)
}
@Transactional(readOnly = true)
fun countLoanedBook(): Int {
return userLoanHistoryQuerydslRepository.count(UserLoanStatus.LOANED).toInt()
}
@Transactional(readOnly = true)
fun getBookStatics(): List<BookStatResponse> {
return bookQuerydslRepository.getStats()
}
}