반응형
N대1의 연관관계를 설정하기 위해서는 아래와 같은 코드로 작성한다.
@ManyToOne
@ToString.Exclude
private Publisher publisher;
위 코드를 작성하면 아래화면과 같이 해당 테이블에 외래키가 자동으로 작성된다.
N대1 연관관계를 맺으면 연관된 테이블에 데이터를 가져올때 get 메소드를 통해서 가져온다.
System.out.println("Publisher: " + user.getReviews().get(0).getBook().getPublisher());
예제코드
Review 클래스 생성
package com.example.bookmanager.domain;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.persistence.*;
import java.util.Calendar;
@Entity
@NoArgsConstructor
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Review extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String content;
private float score;
@ManyToOne
private User user;
@ManyToOne
private Book book;
}
Jpa 사용을 위해 repository 구현
package com.example.bookmanager.repository;
import com.example.bookmanager.domain.Review;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ReviewRepository extends JpaRepository<Review, Long> {
}
테이블 생성 확인
Review 와 마찬가지로 Publisher 클래스 생성
package com.example.bookmanager.domain;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@NoArgsConstructor
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Publisher extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(fetch = FetchType.EAGER)
// new ArrayList<>(): null 예외처리 방지
@JoinColumn(name = "publisher_id")
private List<Book> books = new ArrayList<>();
}
repository 생성
package com.example.bookmanager.repository;
import com.example.bookmanager.domain.Publisher;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PublisherRepository extends JpaRepository<Publisher, Long> {
}
테이블 생성 확인
User 클래스 코드 추가 (review 테이블과 연관관계를 맺는다. 1대N관계)
@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
@ToString.Exclude
private List<Review> reviews = new ArrayList<>();
1대 N관계는 외래키가 생성되지 않는다.
Book 클래스 코드 추가
@OneToMany
@JoinColumn
@ToString.Exclude
private List<Review> reviews = new ArrayList<>();
@ManyToOne
@ToString.Exclude
private Publisher publisher;
테스트 코드
package com.example.bookmanager.repository;
import com.example.bookmanager.domain.Book;
import com.example.bookmanager.domain.Publisher;
import com.example.bookmanager.domain.Review;
import com.example.bookmanager.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import javax.transaction.Transactional;
import java.time.LocalDateTime;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class BookRepositoryTest {
@Autowired
private BookRepository bookRepository;
@Autowired
private PublisherRepository publisherRepository;
@Autowired
private ReviewRepository reviewRepository;
@Autowired
private UserRepository userRepository;
// 테스트를 진행하기 전에 데이터를 입려하는 부분
public void Dto(){
// 기본 데이터 생성 jpa를 이용하여 insert 된다.
userRepository.save(new User("martin", "martin@naver.com", LocalDateTime.now(), LocalDateTime.now()));
userRepository.save(new User("dennis", "dennis@fastcampus.com", LocalDateTime.now(), LocalDateTime.now()));
userRepository.save(new User("sophia", "sophia@fastcampus.com", LocalDateTime.now(), LocalDateTime.now()));
userRepository.save(new User("james", "james@fastcampus.com", LocalDateTime.now(), LocalDateTime.now()));
userRepository.save(new User("martin2", "martin2@fastcampus.com", LocalDateTime.now(), LocalDateTime.now()));
userRepository.save(new User("martin", "martin555@fastcampus.com", LocalDateTime.now(), LocalDateTime.now()));
}
@Test
// @Transactional
// @Transactional
void bookRelationTest(){
Dto();
givenBookAndReview();
User user = userRepository.findByEmail("martin@naver.com");
System.out.println("확인5: " + user.toString());
System.out.println("Review: " + user.getReviews().toString());
System.out.println("Book: " + user.getReviews().get(0).getBook());
System.out.println("Publisher: " + user.getReviews().get(0).getBook().getPublisher());
}
private void givenBookAndReview(){
givenReview(givenUser(), givenBook(givenPublisher()));
}
private User givenUser(){
System.out.println("확인: " + userRepository.findByEmail("martin@naver.com").toString());
return userRepository.findByEmail("martin@naver.com");
}
private Book givenBook(Publisher publisher){
Book book = new Book();
book.setName("jpa 패키지");
book.setPublisher(publisher);
System.out.println("확인: " + publisher.toString());
return bookRepository.save(book);
}
private Publisher givenPublisher() {
Publisher publisher = new Publisher();
publisher.setName("공부하자");
return publisherRepository.save(publisher);
}
private void givenReview(User user, Book book){
Review review = new Review();
// review.setId(1L);
review.setTitle("리뷰 제목");
review.setContent("리뷰 내용");
review.setScore(5.0f);
review.setUser(user);
review.setBook(book);
System.out.println("확인2: " + user.toString());
System.out.println("확인3: " + book.toString());
System.out.println("확인4: " + review.toString());
reviewRepository.save(review);
}
}
콘솔 쿼리
select
books0_.publisher_id as publishe7_1_0_,
books0_.id as id1_1_0_,
books0_.id as id1_1_1_,
books0_.created_at as created_2_1_1_,
books0_.updated_at as updated_3_1_1_,
books0_.author_id as author_i4_1_1_,
books0_.category as category5_1_1_,
books0_.name as name6_1_1_,
books0_.publisher_id as publishe7_1_1_,
bookreview1_.id as id1_2_2_,
bookreview1_.created_at as created_2_2_2_,
bookreview1_.updated_at as updated_3_2_2_,
bookreview1_.average_review_score as average_4_2_2_,
bookreview1_.book_id as book_id6_2_2_,
bookreview1_.review_count as review_c5_2_2_
from
book books0_
left outer join
book_review_info bookreview1_
on books0_.id=bookreview1_.book_id
where
books0_.publisher_id=?
결과 확인
확인5: User(id=1, name=martin, email=martin@naver.com, createdAt=2021-08-08T17:18:17.309, updatedAt=2021-08-08T17:18:17.309, gender=null)
Review: [Review(super=BaseEntity(createdAt=2021-08-08T17:18:17.538, updatedAt=2021-08-08T17:18:17.538), id=1, title=리뷰 제목, content=리뷰 내용, score=5.0, user=User(id=1, name=martin, email=martin@naver.com, createdAt=2021-08-08T17:18:17.309, updatedAt=2021-08-08T17:18:17.309, gender=null), book=Book(super=BaseEntity(createdAt=2021-08-08T17:18:17.538, updatedAt=2021-08-08T17:18:17.538), id=1, name=jpa 패키지, category=null, authorId=null))]
Book: Book(super=BaseEntity(createdAt=2021-08-08T17:18:17.538, updatedAt=2021-08-08T17:18:17.538), id=1, name=jpa 패키지, category=null, authorId=null)
Publisher: Publisher(super=BaseEntity(createdAt=2021-08-08T17:18:17.522, updatedAt=2021-08-08T17:18:17.522), id=1, name=공부하자, books=[Book(super=BaseEntity(createdAt=2021-08-08T17:18:17.538, updatedAt=2021-08-08T17:18:17.538), id=1, name=jpa 패키지, category=null, authorId=null)])
반응형
'프론트엔드 > Vue.js' 카테고리의 다른 글
vue.js 부트스트랩 적용 (0) | 2021.08.09 |
---|---|
Vue Router (페이지 이동) (0) | 2021.08.09 |
컴포지션 API - props, context (0) | 2021.08.05 |
컴포지션 API - 기본옵션과 라이프사이클 (0) | 2021.08.05 |
컴포지션 API - 반응형 데이터 (0) | 2021.08.05 |