[Spring] JPA N:M Relation

WOOK JONG KIM·2022년 11월 20일
0

패캠_java&Spring

목록 보기
57/103
post-thumbnail

실무에선 거의 사용되지 않음

@ManyToMany(N:N)는 One(N:1 or 1:N)이 존재하지 않으면 FK로 삼을 PK를 구하기가 어려움

@ManyToMany 를 설정하면 중간 테이블이 생성 됌
→ ex) author - book → author_books

양쪽에서 Getter 사용 가능

Hibernate: 
    
    create table author (
       id bigint generated by default as identity,
        created_at timestamp,
        updated_at timestamp,
        country varchar(255),
        name varchar(255),
        primary key (id)
    )
Hibernate: 
    
    create table author_books (
       author_id bigint not null,
        books_id bigint not null
    )
Hibernate: 
    
    create table book (
       id bigint generated by default as identity,
        created_at timestamp,
        updated_at timestamp,
        author_id bigint,
        category varchar(255),
        name varchar(255),
        publisher_id bigint,
        primary key (id)
    )

book

public class Book extends BaseEntity{

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

    private String name;

    private String category;

    private Long authorId;


    @OneToOne(mappedBy="book")
    @ToString.Exclude
    private BookReviewInfo bookReviewInfo;

    @OneToMany
    @JoinColumn(name = "book_id") // OneToMany에서 중간 테이블 생성 안하기 위해
    @ToString.Exclude
    private List<Review> reviews = new ArrayList<>();

    @ManyToOne
    @ToString.Exclude
    private Publisher publisher;

    @ManyToMany
    @ToString.Exclude
    private List<Author> authors = new ArrayList<>();

    public void addAuthors(Author... author){
        Collections.addAll(this.authors, author);
    }
}

author

public class Author extends BaseEntity{

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

    private String name;

    private String country;

    @ManyToMany
    @ToString.Exclude
    private List<Book> books = new ArrayList<>();

    public void addBook(Book... book){
        Collections.addAll(this.books, book);
    }
}

중간테이블을 직접 구현 예시

public class BookAndAuthors extends BaseEntity{

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

    @ManyToOne
    private Book book;

    @ManyToOne
    private Author author;
}
	@@OneToMany
    @JoinColumn(name = "author_id")
    @ToString.Exclude
    private List<BookAndAuthors> bookAndAuthors = new ArrayList<>();
    
    @OneToMany
    @JoinColumn(name = "book_Id")
    @ToString.Exclude
    private List<BookAndAuthors> BookAndAuthors = new ArrayList<>();
();

// 둘 공통 메서드
public void addBookAndAuthors(BookAndAuthors... bookAndAuthors){
        Collections.addAll(this.BookAndAuthors, bookAndAuthors);
    }

테스트 코드 예시

bookRepository.findAll().get(2).getBookAndAuthors().forEach(o -> System.out.println(o.getAuthor()));
authorRepository.findAll().get(0).getBookAndAuthors().forEach(o -> System.out.println(o.getBook()));
profile
Journey for Backend Developer

0개의 댓글