JPA로 엔티티 다대다 단방향 매핑하기

CHEESE·2022년 7월 8일
0

나에게는 테이블 2개와 이 테이블의 연관관계를 매핑하는 테이블 1개가 있다. JPA를 (거의) 처음 접하는 나는 원래 쓰던 Mybatis나 써야지 하고 생각했었다... JPA를 이용해서 불필요한 코드를 확 줄일 수 있었다.

엔티티 클래스 만들기

우리의 경우에는 테이블 개수에 맞게 엔티티 클래스를 설계할 필요가 없다.
연관관계를 매핑하는 테이블을 제외하고 기본 엔티티 클래스 2개만 만들면 된다.

Post

@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = "POST_NO")})
public class Post{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "POST_NO")
    private Integer postNo;

    ...
}

Tag

@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = "TAG")})
public class Tag {
    @Id
    private String tag;
}

관계 매핑하기

이제 관계 주인이 되는 엔티티 클래스를 만져보자.
우리에게는 @ManyToMany@JoinTable, @JoinColumn만 있으면 된다.

Post

@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = "POST_NO")})
public class Post{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "POST_NO")
    private Integer postNo;

    @ManyToMany
    @JoinTable(name = "POST_TAG", joinColumns = @JoinColumn(name = "POST_NO"), inverseJoinColumns = @JoinColumn(name = "TAG"))
    private List<Tag> tags = new ArrayList<>();
}

@JoinTable은 연결 테이블을 지정한다.
joinColumns는 현재 위치의 객체(여기에서는 Post)와 매핑할 조인 컬럼 이름,
inverseJoinColumn는 반대편 객체(여기에서는 Tag)와 매핑할 조인 컬럼 이름을 지정한다.

데이터 넣기

데이터를 넣는 작업은 @ManyToMany가 알아서 연관 테이블에 값을 넣어준다.

public class TestService{
	private final EntityManager em;
    
    @Transactional
    public void insertPost(Post post) {
        for(Tag tag : post.getTags()){
            System.out.println(tag.toString());
            em.persist(tag);
        }

        em.persist(post);
    }
}

@ManyToMany의 한계

연결 테이블에 외래키만 담지 않고 추가적인 컬럼이 들어가는 경우 사용할 수 없다.

0개의 댓글