시험문제
1. 회원 테이블이 완성되어 있지 않습니다.
.http 파일의 Q1. 회원가입 API에 따라 테이블을 작성해 주세요.
entity 패키지의 member 클래스를 완성해 주세요.
예상 return값 (4번문제 풀기 전)// A1. Response [ { "id": 1, "email": "sparta@sparta.com", "password": "4321", "address": "부산시", "phoneNumber": "01012341234", "nickname": "스파르타", "bookStore": null }, { "id": 2, "email": "hanghae99@sparta.com", "password": "1234", "address": "서울시", "phoneNumber": "01012345678", "nickname": "르탄이", "bookStore": null } ]
2. 서점에 등록된 책의 가격과 재고를 수정해야 합니다.
.http 파일의 Q2. *서점에 책 등록된 책 수량 수정 API*를 완성해 주세요.
service 패키지, TestService의 updateBook 메서드를 완성해 주세요.
예상 return값
.http를 확인해 주세요.// A2. Response [ { "id": 1, "title": "자바의 정석 3판", "author": "남궁성", "price": 10000, "stock": 100, "bookStore": { "name": "스파르타 서울" } } ]
3. “자바의정석”책을 서울점에서 부산점으로 옮기려고 합니다.
현재 만들어진 *Q3. 부산점에 자바의 정석 책 등록 API*로는 어째서인지 정보가 수정되지 않습니다.
올바르게 작동하도록 수정해 주세요.
service 패키지, TestService의 transferBook 메서드를 완성해 주세요.
예상 return값// A3. Response [ { "id": 1, "title": "자바의 정석 3판", "author": "남궁성", "price": 10000, "stock": 100, "bookStore": { "name": "스파르타 부산" } }, { "id": 2, "title": "자바 ORM 표준 JPA 프로그래밍", "author": "김영한", "price": 20000, "stock": 4, "bookStore": { "name": "스파르타 부산" } } ]
4. 회원 테이블과 책 테이블간 다대다 매핑이 되어 있습니다.
Purchase 테이블을 중간 테이블로 설정하여 1:N, M:1 의 관계로 바꿔 주세요.
entity 패키지의 purchase 클래스, 연관된 클래스들을 수정해 주세요.
[http://localhost:8080/h2-console](<http://localhost:8080/h2-console>) 를 확인해 주세요.
5. 회원 테이블에 서점 테이블 FK 컬럼명을 Sparta_Store_Id로 바꿔주세요.
단, Member 클래스와 BookStore 클래스를 변경시키지 않아야 합니다.
entity 패키지의 member클래스를 완성해 주세요.
예상 return값
[http://localhost:8080/h2-console](<http://localhost:8080/h2-console>) 를 확인해 주세요.
서술형 문제
6. JPA에서, 기존의 정보를 수정하는 기능 작성 시 save 메서드가 필요 없는 이유와 동작 원리에 대해 서술해 주세요.
제출한 답안
Q1. Member 클래스 코드를 제출해 주세요.
package com.example.jpa_relation_test.entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@NoArgsConstructor
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
private String password;
private String address;
private String phoneNumber;
private String nickname;
@ManyToOne
@JoinColumn(name = "book_store_id")
private BookStore bookStore;
@ManyToMany
private List<Book> books = new ArrayList<>();
public Member(String email, String password, String address, String phoneNumber, String nickname) {
this.email = email;
this.password = password;
this.address = address;
this.phoneNumber = phoneNumber;
this.nickname = nickname;
}
}
Q2. updateBook 메서드 코드, BookRepository, Book 클래스를 제출해 주세요.
// updateBook 메서드 코드
@Transactional
public void updateBook(Book book, Long bookStoreId, Long bookId) {
Optional<Book> optionalBook = bookRepository.findById(bookId);
if (optionalBook.isPresent()) {
Book existingBook = optionalBook.get();
existingBook.updateTitle(book.getTitle());
existingBook.updateAuthor(book.getAuthor());
existingBook.updatePrice(book.getPrice());
existingBook.updateStock(book.getStock());
if (bookStoreId != null) {
Optional<BookStore> optionalBookStore = bookStoreRepository.findById(bookStoreId);
if (optionalBookStore.isPresent()) {
BookStore bookStore = optionalBookStore.get();
existingBook.updateBookStore(bookStore);
} else {
throw new RuntimeException("해당 ID에 해당하는 서점을 찾을 수 없습니다.: " + bookStoreId);
}
}
bookRepository.save(existingBook);
} else {
System.out.println(bookId + "에 해당하는 책을 찾을 수 없습니다.");
}
}
// BookRepository
public interface BookRepository extends JpaRepository<Book, Long> {
List<Book> findByBookStoreId(Long bookStoreId);
}
// Book 클래스
package com.example.jpa_relation_test.entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@NoArgsConstructor
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String author;
@Column(nullable = false)
private Integer price;
private Integer stock;
@ManyToOne
@JoinColumn(name = "bookstore_id")
private BookStore bookStore;
@ManyToMany
@JoinTable(
name = "member_book",
joinColumns = @JoinColumn(name = "book_id"),
inverseJoinColumns = @JoinColumn(name = "member_id")
)
private List<Member> members = new ArrayList<>();
public Book(String title, String author, Integer price, Integer stock) {
this.title = title;
this.author = author;
this.price = price;
this.stock = stock;
}
public void updateTitle(String title) {
this.title = title;
}
public void updateAuthor(String author) {
this.author = author;
}
public void updatePrice(Integer newPrice) {
this.price = newPrice;
}
public void updateStock(Integer newStock) {
this.stock = newStock;
}
public void updateBookStore(BookStore bookStore) {
this.bookStore = bookStore;
}
}
Q3. transferBook 메서드 코드, Book 클래스 코드를 제출해 주세요.
// transferBook 메서드 코드
public void transferBook(Long bookId, Long bookStoreId) {
Book book = bookRepository.findById(bookId)
.orElseThrow(() -> new RuntimeException("해당 아이디의 책을 찾을 수 없습니다. : " + bookId));
BookStore bookStore = bookStoreRepository.findById(bookStoreId)
.orElseThrow(() -> new RuntimeException("해당 아이디의 서점을 찾을 수 없습니다.: " + bookStoreId));
book.updateBookStore(bookStore);
bookRepository.save(book);
bookStore.addBook(book);
}
}
// Book 클래스 코드
package com.example.jpa_relation_test.entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@NoArgsConstructor
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String author;
@Column(nullable = false)
private Integer price;
private Integer stock;
@ManyToOne
private BookStore bookStore;
@ManyToMany
@JoinTable(
name = "member_book",
joinColumns = @JoinColumn(name = "book_id"),
inverseJoinColumns = @JoinColumn(name = "member_id")
)
private List<Member> members = new ArrayList<>();
public Book(String title, String author, Integer price, Integer stock) {
this.title = title;
this.author = author;
this.price = price;
this.stock = stock;
}
public void updateTitle(String title) {
this.title = title;
}
public void updateAuthor(String author) {
this.author = author;
}
public void updatePrice(Integer newPrice) {
this.price = newPrice;
}
public void updateStock(Integer newStock) {
this.stock = newStock;
}
public void updateBookStore(BookStore bookStore) {
this.bookStore = bookStore;
}
}
Q4. Purchase, Book, Member 클래스 코드를 제출해 주세요.
// Purchase
package com.example.jpa_relation_test.entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Entity
@Getter
@NoArgsConstructor
public class Purchase {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private Member member;
@ManyToOne
private Book book;
private int quantity;
public Purchase(Member member, Book book, int quantity) {
this.member = member;
this.book = book;
this.quantity = quantity;
}
}
// Book
package com.example.jpa_relation_test.entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@NoArgsConstructor
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String author;
@Column(nullable = false)
private Integer price;
private Integer stock;
@ManyToOne
@JoinColumn(name = "bookstore_id")
private BookStore bookStore;
@ManyToMany
@JoinTable(
name = "member_book",
joinColumns = @JoinColumn(name = "book_id"),
inverseJoinColumns = @JoinColumn(name = "member_id")
)
private List<Member> members = new ArrayList<>();
public Book(String title, String author, Integer price, Integer stock) {
this.title = title;
this.author = author;
this.price = price;
this.stock = stock;
}
public void updateTitle(String title) {
this.title = title;
}
public void updateAuthor(String author) {
this.author = author;
}
public void updatePrice(Integer newPrice) {
this.price = newPrice;
}
public void updateStock(Integer newStock) {
this.stock = newStock;
}
public void updateBookStore(BookStore bookStore) {
this.bookStore = bookStore;
}
public Long getId() {
return id;
}
}
// Member
package com.example.jpa_relation_test.entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@NoArgsConstructor
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
private String password;
private String address;
private String phoneNumber;
private String nickname;
@ManyToOne
@JoinColumn(name = "book_store_id")
private BookStore bookStore;
@ManyToMany(mappedBy = "members")
private List<Book> books = new ArrayList<>();
public Member(String email, String password, String address, String phoneNumber, String nickname) {
this.email = email;
this.password = password;
this.address = address;
this.phoneNumber = phoneNumber;
this.nickname = nickname;
}
}
Q5. Member 클래스 코드를 제출해 주세요.
package com.example.jpa_relation_test.entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@NoArgsConstructor
@Table(name = "member")
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
private String password;
private String address;
private String phoneNumber;
private String nickname;
@ManyToOne
@JoinColumn(name = "Sparta_Store_Id")
private BookStore bookStore;
@ManyToMany(mappedBy = "members")
private List<Book> books = new ArrayList<>();
public Member(String email, String password, String address, String phoneNumber, String nickname) {
this.email = email;
this.password = password;
this.address = address;
this.phoneNumber = phoneNumber;
this.nickname = nickname;
}
public void addBook(Book book) {
this.books.add(book);
book.getMembers().add(this);
}
public void removeBook(Book book) {
this.books.remove(book);
book.getMembers().remove(this);
}
}
Q6. JPA에서, 기존의 정보를 수정하는 기능 작성 시 save 메서드가 필요 없는 이유와 동작 원리에 대해 서술해 주세요.
JPA는 엔티티를 데이터베이스에 저장하거나 수정할 때 도와줍니다., 이때 엔티티를 수정해도 save 메서드를 호출할 필요가 없는 이유는 JPA가 엔티티의 상태 추적을 잘하고 있기 때문입니다. 이미 데이터베이스에서 정보를 가져와서 Java 객체로 변환했다고 가정해봅시다. 이 객체는 JPA의 영속성 컨텍스트에 의해 추적되고 있습니다. 이 상태에서 우리가 객체를 변경한다면, JPA는 이 변경 내용을 감지하고 있습니다. 변경 내용을 데이터베이스에 반영하려면 save 메서드를 호출하지 않고도 변경된 객체를 다시 영속성 컨텍스트에 넣어주면 됩니다. 그러면 JPA는 변경된 내용을 데이터베이스에 알아서 반영해 줄 수 있습니다. JPA는 객체를 수정할 때마다 이것을 추적하고,우리가 DB에 저장하거나 수정할 때 이것들을 처리해줍니다. 그래서 그냥 객체를 변경하고, JPA가 나머지를 처리하게 할 수 있습니다.
결과
급하게 구현하다보니까 코드가 좀 더럽게(?) 짠다는 느낌을 받았는데, 이렇게 보니까 진짜 체감이 확 된다...
감점된 부분은 구매 테이블 연결을 안했다...(바보같은 나...)
시간 될 때 코드 수정해서 다시 테스트 진행해봐야겠다.
'항해99 > 시험 리뷰' 카테고리의 다른 글
[항해99] Spring 주특기3 시험 리뷰 (0) | 2024.03.13 |
---|---|
[항해99] Spring 주특기1 시험 리뷰 (0) | 2024.02.26 |
[항해99] 기초 프로그래밍2 시험 리뷰 (0) | 2024.02.19 |