-
Notifications
You must be signed in to change notification settings - Fork 2
Spring base sw #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: JavaBase
Are you sure you want to change the base?
Spring base sw #15
Conversation
- Controller 클래스가 담길 디렉터리 생성 - Entity 클래스가 담길 디렉터리 생성 - Repository 클래스가 담길 디렉터리 생성 - Service 클래스가 담길 디렉터리 생성
- 서비스의 핵심 엔티티인 Book 클래스 작성 - Book의 분류를 나타내는 BookCategory 클래스 작성 - Book의 상태를 나타내는 BookStatus 클래스 작성
BookRepository의 인터페이스 작성
- BookRepository를 구현한 MemoryBookRepository를 작성 - Book 엔티티에 Lombok의 Getter, Builder 적용
MemoryBookRepository를 사용하는 BookService 구현
- BookService를 사용하는 BookController 구현 - Book 엔티티에 생성자 추가
- BookController의 registryBook 메서드에 DTO로 입력 받도록 수정 - BookService도 DTO를 가공하여 Book을 만들도록 수정
- 클라이언트에게 반환할 최상위 HTTP Response 클래스 작성 - 디렉터리 구조 일부 변경
- 예외를 처리하여 책 등록 및 조회 기능 모두 구현 - 추후 대여와 반납을 구현할 예정
- 책 대여를 위힌 요청 DTO인 BorrowBookDTO 생성 - BookStatus의 Borrawing을 Borrowing으로 수정 - BookController의 책 대여에 관한 메서드 최초 작성
- 책을 대출하는 기능을 구현 - BookRepository에 최소한의 Method만 남기고 모두 삭제
책을 반납하는 기능을 구현
- 책의 이름을 검색하는 기능을 구현 - 전체적인 코드 스타일 적용
- MariaDB와 연동을 하기 위해 의존성 추가 - MariaDB와 Service 클래스 간의 통신을 위한 StatementBookRepository 구현
기존의 StatementBookRepository를 JdbcBookRepository로 이름 수정
JdbcRepository create
- JdbcBookRepository을 Service에 주입하도록 수정 - Quantifier를 Service에만 적용
PreparedStatement 를 이용해서 insert 문을 통한 책 등록 기능 구현
isbn 을 통한 책 조회를 위한 기능 추가
이미 있는 isbn 을 가진 책이 있는지 확인하는 기능을 추가
| try { | ||
| connection = DriverManager.getConnection(DATABASE_URL); | ||
| statement = connection.createStatement(); | ||
| System.out.println("DB Connection Succeed"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://hudi.blog/do-not-use-system-out-println-for-logging/
위 링크 참고하여 관련된 내용들 일괄적으로 적절하게 수정 바랍니다.
| books.add(book); | ||
| } | ||
|
|
||
| resultset.close(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
close 메서드는 try-catch의 finally 문에서 호출하는 것이 좋아보입니다. (예외가 발생하는 경우에도 close 할 수 있어야 함.)
또, static이 붙은 경우에는 그 특성을 잘 고려하여 close를 호출 할 것인지를 잘 생각해야 합니다.
| @Override | ||
| public Book save(Book book) { | ||
| return null; | ||
| String sql = "Insert into Book values(NULL, ?, ?, ?, ?, ?)"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
insert into Book (Column1, Column2, ..., ColumnN) values (?, ?, ... ?) 의 형식으로 쿼리를 구성하는 것이 좋아보입니다.
또, ID 값의 경우 Book 테이블 생성 과정에서 ID 값에 대한 auto_increment을 적용하였기 때문에 Null 값으로 넣을 필요는 없습니다.
|
|
||
| ResultSet resultSet = preparedStatement.executeQuery(); | ||
|
|
||
| if (resultSet.next()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
앞서 작성한 쿼리를 개선하면서 이 부분도 보다 더 간단하게 개선할 수 있을 것으로 보입니다.
| book.setTitle(resultSet.getString("title")); | ||
| book.setIsbn(resultSet.getString("isbn")); | ||
| book.setAuthor(resultSet.getString("author")); | ||
| book.setCategory(BookCategory.valueOf(resultSet.getString("book_category"))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
book의 setter 메서드에 값을 입력할 때 내부적으로 valueOf와 getter 호출이 일어나고 있습니다. 이는 앞에서 간단한 변수로 빼두어 사용하면 간결할 것 같습니다.
| System.out.println(e.getMessage()); | ||
| return null; | ||
| } | ||
| return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
메서드가 null을 반환하는 경우는 없어야 합니다. 이 사항은 모든 메서드에 일괄 적용해주시기 바랍니다.
| @Override | ||
| public boolean existsByIsbn(String isbn) { | ||
| return false; | ||
| String sql = "SELECT * from Book where isbn = ?"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 쿼리는 아래와 같이 개선할 수 있습니다.
SELECT isbn EXISTS (SELECT isbn FROM book WHERE isbn = ?)
위와 같이 exists와 서브쿼리를 사용하면 입력으로 주어진 isbn과 일치하는 레코드를 찾은 시점에 검색을 종료합니다.
그에 반하여 지금 작성한 쿼리는 입력으로 주어진 isbn과 일치하는 레코드를 찾아도 테이블의 모든 내용을 찾아가며 추가적으로 일치하는 레코드를 찾게 됩니다.
또, 지금처럼 단순 조회(= 값이 있는 지 혹은 없는 지와 같은 조회)의 경우, select 쿼리가 반환하려는 컬럼을 아래와 같은 와일드 카드(*)로 주게 되면, 가져오는 컬럼이 많아지게 되므로 비효율적입니다.
SELECT * from Book where isbn = ?
따라서, 아래처럼 하나의 컬럼만을 가져오는 것이 더 효율적일 것입니다.
SELECT isbn from Book where isbn = ?
Auto_Increment 로 id 값을 추가해 줄 필요가 없다.
# Conflicts: # src/main/java/com/example/demo/repository/JdbcBookRepository.java
- JPA 적용을 위한 JpaBookRepository 생성 - Service 에 JpaBookRepository 적용 - JdbcRepository 의 MariaDB connect 부분 주석 처리
반납에 경우 @transactional을 대여에 경우 save 를 사용 둘다 업데이트 수행이 가능
findAll 기능
findAll 의 경우 Book 테이블의 전부를 가져오는 기능으로
SQL 문이 변하지 않는 정적이므로 Statement 로 SQL 문을 수행하도록 구현
save 기능
책 등록 기능 추가를 위해 이번에는 POST 요청으로 얻은 인자를 이용해야 하므로 PreparedStatement 를 사용
findByIsbn 기능
마찬가지로 isbn 인자를 SQL 문으로 사용하기 때문에 PreparedStatement 를 사용
일단 모든 Controller 메서드에 대해서는 테스트 성공