728x90

 

토이 프로젝트를 진행하면서 카테고리를 만드는데 무한 뎁스로 만드는 과정을 기록하려 한다.

Stack : Java,Gradle, Spring data jpa ,Mysql

위 사진 처럼 유연하게 설계하여 무한하게 카테고리가 생성이 가능한 로직을 구현할것이다.

 

🔓요구조건 

  1. Entity 구현
    • 하나의 테이블에서 구현해야하기 떄문에 Self Join 사용하여 구현 
  2. Repository 인터페이스 구현
    • Spring data JPA를 사용을 위해 JpaRepository를 상속 받는다.
  3. DTO 구현
    • Entity는 DB를 생성하고 DB를 가지고 계층간의 소통을 하기 위해 DTO를 구현할 것이다.
    • Entity에서 list로 담은 childCategory는 DTO에서는 Map으로 구현한다.
  4. Service 구현 
    • Save : 카테고리를 생성하는 로직이다.( 카테고리 이름이 중복되는지 검증 후 생성,부모 자식 카테고리를 가지고 있는지 검증 )
    • delete :  카테고리를 삭제하는 로직이다. ( 자식 카테고리가 존재하면 삭제할 수 없다.)
    • update : 카테고리를 업데이트하는 로직이다.
    • get : 카테고리를 Id와 name으로 조회하는 로직이다. (자식 카테고리 존재시 같이 조회된다.)
  5. Service Test Code 구현 
    • 테스트 코드는 항상 중요하다.
    • 서비스 단위 테스트 코드이다.
  6. Controller 구현
    • Api 통신을 위해 반환 로직을 구현

 

 

1. Entity 구현 

  • 하나의 테이블에서 무한 뎁스를 구현해야하기 때문에 Self Join을 사용할 것이다.
@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Category {

    @Id@GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "category_id")
    private Long id;

    private String categoryName;

    @ManyToOne(fetch = FetchType.LAZY)
    private Category parentCategory;

    @OneToMany(mappedBy = "parentCategory")
    private List<Category>childCategory =new ArrayList<>();

 

    @Builder
    public Category(String categoryName, Category parentCategory, List<Category> childCategory) {
        this.categoryName = categoryName;
        this.parentCategory = parentCategory;
        this.childCategory = childCategory;

    }
}
  • 여기서 주의깊게 볼것은 parentCategory childCategory이다. 
  • 서로 물고 무는 무한뎁스 구조를 위해 두 칼럼끼리 연관관계를 맺고 mappedBy속성을 통해서 parentCategory를 연관 관계 주인으로 설정해준다.(주인을 설정해주지 않으면 조회시 계속 서로를 참조하는 무한루프가 발생한다!)
  • JPA에서 연관관계를 설정할때 ManyToOne,OneToOne은 fetchType.EAGER이 default이다. 그래서 지연 참조(detchType.Lazy)를 사용해줘야 N+1 이슈 등 문제가 생기지 않는다.

2.Repository

public interface CategoryRepository extends JpaRepository<Category,Long> {
    Optional<Category>findByCategoryName(String name);
    Boolean existsByCategoryName(String name);
}
  • extends JpaRepository는 Spring data jpa를 사용하기 위해 무조건 상속 받아야한다.
  • Spring data jpa는 메서드 이름명으로 검색 조건을 만들수 있다.(find + By + Entity 필드값)
  • existsByCateoryName은 카테고리 이름이 중복되는지 검증하기 위해 Boolean 타입으로 리턴 받는다.

 

다음 포스팅은 서비스와 서비스에 대한 테스트 코드를 포스팅할 예정이다.

 

😸예제 코드

https://github.com/ryudongjae/blog-ex

 

GitHub - ryudongjae/blog-ex: 📁블로그 예제 코드

📁블로그 예제 코드 . Contribute to ryudongjae/blog-ex development by creating an account on GitHub.

github.com

 

728x90