Spring 브랜드콘 클론3 : ManyToMany

춤인형의 개발일지·2025년 1월 16일

Spring실습

목록 보기
21/40

25/1/

ManyToMany

다 대 다(N:M)인 관계에서는 관계매핑을 어떻게 사용할까?

@ManyToMany

1:N관계에서 사용하는 어노테이션을 사용할 수 있다.
하지만 이런 관계는 주로 사용하지 않는다고 한다.

❗️클래스를 하나 더 만들어 1:N 관계로 만들어준다.

즉, 브랜드와 카테고리는 다대다 관계이기 때문에, 연결해주는 클래스를 하나 더 만들어준다.

  • 보통 클래스명은 BrandCategory 매핑할 2가지의 데이터들로 구성한다.
  • Brand를 생성할 때 category 넣으니까 brand가 먼저이다. 따라서 brand를 먼저 작성해준다.
package brandkon.brand;

import brandkon.category.Category;
import jakarta.persistence.*;

@Entity
public class BrandCategory {

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

    @ManyToOne
    private Brand brand;

    @ManyToOne
    private Category category;
}

1) 구성 형태
브랜드 | 브랜드카테고리 | 카테고리
1 : N : 1

2) 필드
필드는 딱 연결되어 있는 데이터만 들어가 있다.

brand, category를 서로 1:N관계로만 설정되어 있는 부분을 brandCategory로 수정해준다.

//기존
   @ManyToOne
    private Category category;
    
 //수정
 @OneToMany(mappedBy = "brand")
    private List<BrandCategory> brandCategory;

그럼 실제로 service에서 수정해준다.

//1:N관계일 때(기존코드)
public List<BrandResponse> read(String category) {
        List<Brand> categorySlug = brandRepository.findByCategorySlug(category);
        return categorySlug.stream().map(brand -> new BrandResponse(
                brand.getId(),
                brand.getName(),
                brand.getImageUrl()
        )).toList();
    }
    
// N:M관계일때
    public List<BrandResponse> read(String category) {
        List<BrandCategory> byCategorySlug = brandCategoryRepository.findByCategorySlug(category);
        return byCategorySlug.stream().map(brandCategory ->
                new BrandResponse(
                        brandCategory.getBrand().getId(),
                        brandCategory.getBrand().getName(),
                        brandCategory.getBrand().getImageUrl()
                )).toList();
    }

기존코드는 brandRepository로 활용하고 있지만, 이제는 brandcategory를 활용해서 가져오면 된다.

//1:n 관계
    public BrandResponse oneBrandRead(Long brandId) {
        Brand brand = brandRepository.findById(brandId).orElseThrow();
        return new BrandResponse(brandId, brand.getName(), brand.getImageUrl());
    }

//n:m
public BrandResponse oneBrandRead(Long brandId) {
        BrandCategory brandCategory = brandCategoryRepository.findById(brandId).orElseThrow();
        return new BrandResponse(
                brandCategory.getBrand().getId(),
                brandCategory.getBrand().getName(),
                brandCategory.getBrand().getImageUrl());
    }

이런식으로 작성된다.


😐 느낀점

N:M을 사용하기 위해서는 새로운 클래스가 필요하다.
이 클래스 자체는 어떤 중요한 역할을 하진 않지만, 이어주는 역할이기에 꼭 필요하다.
중간 다리의 repository도 꼭 필요하며 이걸 사용해서 보통 응용하면 된다.

0개의 댓글