Spring Boot (15) 연관관계 매핑 실습(3)

넙데데맨·2022년 9월 5일
0
post-custom-banner

일대다 단방향 매핑

  1. 카테고리 테이블 생성
    카테고리와 상품은 1:N 관계이다.

Category.java

@Entity
@Getter
@Setter
@NoArgsConstructor
@ToString
@EqualsAndHashCode
@Table(name = "category")
public class Category {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true)
    private String code;

    private String name;
    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name ="category_id")
    private List<Product> products = new ArrayList<>();
}

애플리케이션 실행 시 Product 테이블에 category_id 컬럼이 외래키로 추가되있는 것을 확인할 수 있다.
OneToMany@JoinColumn을 사용하면 별도의 설정을 하지 않아도 일대다 단방향 연관관계가 매핑된다.

단점

  • 테이블에서는 N쪽에서 외래키를 관리하는 데 1이 주인인 관계에서 N쪽에 외래키가 생성된다.
  • 따라서 1:N 관계가 필요하다면 N:1 양방향 관계로 설정해서 N쪽에서 1쪽을 조회할 필요가 없어도 N쪽을 연관관계의 주인으로 설정해 사용하는 것이 좋다.

다대다 매핑

  • 실무에서 거의 사용 X
  • 예를 들면 한 종류의 상품이 여러생산 업체를 통해 생산
    생산업체 한 곳이 여러 상품을 생산하는 관계
  • 서로를 리스트로 가지는 구조가 되며 이럴 경우 일대다 혹은 다대일 관계로 해소

다대다 단방향 매핑

생산 업체 엔티티 생성
Producer

@Entity
@Getter
@Setter
@NoArgsConstructor
@ToString(callSuper = true)
@Table(name = "producer")
public class Producer extends BaseEntity{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String code;

    private String name;
    @ManyToMany
    @ToString.Exclude
    private List<Product> products = new ArrayList<>();

    public void addProduct(Product product){
        products.add(product);
    }
}

다대다 매핑 시 외래키가 별도로 추가되지 않고 product와 producer의 중간 테이블이 생성되어 product와 producer에서 id 값을 가져와 외래키를 관리하는 것을 볼 수 있다.

@SpringBootTest
public class ProducerRepositoryTest {
    @Autowired
    ProducerRepository producerRepository;
    @Autowired
    ProductRepository productRepository;

    @Test
    @Transactional
    void relationshipTest(){
        Product product1 = saveProduct("동글 펜",100,1000);
        Product product2 = saveProduct("네모 공책",200,2000);
        Product product3 = saveProduct("지우개",300,3000);

        Producer producer1 = saveProducer("콤마");
        Producer producer2 = saveProducer("세미콜론");
		/** @transaction 필요 구간
        */
        producer1.addProduct(product1);
        producer1.addProduct(product2);

        producer2.addProduct(product2);
        producer2.addProduct(product3);

        producerRepository.saveAll(Lists.newArrayList(producer1,producer2));
        System.out.println(producerRepository.findById(1L).get().getProducts());

    }

    private Product saveProduct(String name,Integer price, Integer stock){
        Product product = new Product();
        product.setName(name);
        product.setPrice(price);
        product.setStock(stock);
        return productRepository.save(product);
    }

    private Producer saveProducer(String name){
        Producer producer = new Producer();
        producer.setName(name);
        return producerRepository.save(producer);
    }
}

트랜잭션이 끊어지는 것을 방지하기 위해 @Transactional 설정한다.

다대다 양방향 매핑

다대다 양방향은 양쪽으로 단방향 매핑을 해준다.

profile
차근차근
post-custom-banner

0개의 댓글