본문 바로가기

IT/JPA

JPA Entity 조인 테이블 연관관계에 대해 알아보자

JPA 연관관계 매핑 - 조인 테이블(@JoinTable)

  • 조인 테이블
DB에 연관관계를 맺는 방법은 크게 두가지이다.
1. 외래키를 가지고 연관관계를 맺는 조인 컬럼 방식
2. 테이블과 테이블 사이에 조인테이블을 만들어 연관관계를 맺는 방식

여기서는 2의 경우에 대해서 알아보도록 한다.

1:1 조인 테이블

조인테이블의 경우 외래키를 사용하는 방법과는 다르게 테이블이 하나 더 생기때문에 관리해야 할 테이블이 늘어나는 단점이 있다

@Entity
class product (

    @Id
    @Column(name = "product_id")
    val id: Long,

    @Column(name = "product_name")
    val product_name: String,

    @OneToOne
    @JoinTable(name = "product_shop",
                        joinColumns = @JoinColumn(name = "product_id"),
                        inverseJoinColumns = @JoinColumn(name = "shop_id")
    )
    val shop:Shop,
)



@Entity
class Shop (

    @Id
  @Column(name = "shop_id")
  val id:Long,

  @Column(name = "shop_name")
  val shop_name:String

)
  • 테스트
val shop = Shop(1,"곰이상점")
em.persist(shop)

val product = Product(2, "오똑이 개껌")
product.shop = shop
em.persist(shop)
  • 테스트 결과

select * from product

PRODUCT_ID PRODUCT_NAME
2 오똑이 개껌

select * from shop

SHOP_ID SHOP_NAME
1 곰이 상점

select * from product_shop

PRODUCT_ID SHOP_ID
2 1

1:N 조인테이블

@Entity
class Product(
    @Id
    @Column(name = "product_id")
    val product_id: Long,

    @Column(name = "product_name")
    val product_name: String,

    @OneToMany
    @JoinTable(name = "product_shop",
                        joinColumns = @JoinColumn(name = "product_id"),
                        inverseJoinColumns = @JoinColumn(name = "shop_id")
    )
    val shop: List<Shop>
)

@Entity
class Shop(
    @Id
    @Column(name = "shop_id")
    val shop_id: Long,

    @Column(name = "shop_name")
    val shop_name: String,
)
  • 테스트
val shop = Shop(1,"곰이상점")
em.persist(shop)

val shop1 = Shop(2,"똘이상점")
em.persist(shop1)

val product = Product(2, "오똑이 개껌")
product.addShop = shop
product.addShop = shop1
em.persist(product)
  • 테스트 결과

select * from product

PRODUCT_ID PRODUCT_NAME
2 오똑이 개껌

select * from shop

SHOP_ID SHOP_NAME
1 곰이 상점
2 똘이 상점

select * from product_shop

PRODUCT_ID SHOP_ID
2 1
2 2

N:1 조인테이블

@Entity
class Product(

    @Id
    @Column(name = "product_id")
    val productId: Long,

    @Column(name = "product_name")
    val productName: String,

    @ManyToOne
    val shop:Shop

)

@Entity
class Shop(

    @ID
    @Column(name = "shop_id")
    val shop_id: String,

    @Column(name = "shop_name")
    val shop_name: String,

    @OneToMany
  @JoinTable(name = "product_shop",
            joinColumns = @JoinColumn(name = "product_id"),
            inverseJoinColumns = @JoinColumn(name = "shop_id")

  val product: List<Product>
)
  • 테스트
val shop = Shop(1, "곰이 상점")

val product = Product(2, "오똑이 개껌")
product.setShop = shop
em.persist(product)

val product1 = Product(3, "농숨 개껌")
product1.setShop = shop
em.persist(product1)

shop.addProduct = product
shop.addProduct = product1
em.persist(shop)
  • 테스트 결과

select * from product

PRODUCT_ID PRODUCT_NAME
2 오똑이 개껌
3 농숨 개껌

select * from shop

SHOP_ID SHOP_NAME
1 곰이 상점

select * from product_shop

PRODUCT_ID SHOP_ID
2 1
3 1

N:M 조인테이블

@Entity
class Product(
    @Id
    @Column(name = "product_id")
    val product_id: Long,

    @Column(name = "product_name")
    val product_name: String,

    @ManyToMany
  @JoinTable(name = "product_shop",
            joinColumns = @JoinColumn(name = "product_id"),
            inverseJoinColumns = @JoinColumn(name = "shop_id")
  val shop: List<Shop>
)

@Entity
class Shop(
    @Id
    @Column(name = "shop_id")
    val shop_id: Long,

    @Column(name = "shop_name")
    val shop_name: String,

)
  • 테스트
val shop = Shop(1, "곰이 상점")
em.persist(shop)
val shop1 = Shop(2, "똘이 상점")
em.persist(shop1)

val product = Product(1, "오똑이 개껌")
val product1 = Product(2, "농숨 개껌")

product.addShop = shop
em.persist(product)

product1.addShop = shop
product1.addShop = shop1
em.persist(product1)
  • 테스트 결과

select * from product

PRODUCT_ID PRODUCT_NAME
1 오똑이 개껌
2 농숨 개껌

select * from shop

SHOP_ID SHOP_NAME
1 곰이 상점
2 똘이 상점

select * from product_shop

PRODUCT_ID SHOP_ID
1 1
2 1
2 2

정리

조인테이블을 이용한 연관관계에 대해 알아보았습니다.

조인테이블이 이용한 연관관계 매핑은 실무에서도 자주 사용되니 잘 알아 두기 위해 정리 했습니다.