어드민 프로젝트 mapstruct 적용 - 1

2025. 5. 26. 16:04·어드민 프로젝트

entity

@Entity
@Getter
public class Menu {

    @Comment("식별자")
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Comment("메뉴 이름")
    @Column(name = "menu_name", nullable = false)
    private String menuName;

    @Comment("메뉴 순서")
    @Column(name = "sort_order", nullable = false)
    private int sortOrder;

    @Comment("사용 여부")
    @Column(name = "is_use", nullable = false)
    private Boolean isUse;

    @Comment("부모 메뉴")
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_menu_id")
    private Menu parent;

    @Comment("자식 메뉴")
    @OneToMany(mappedBy = "parent")
    private List<Menu> children = new ArrayList<>();
}

 

DTO

@Getter
@Setter
public class MenuResponse {
    private Long id;
    private String menuName;
    private int sortOrder;
    private Boolean isUse;
    private Long parentId;
    private List<MenuResponse> children;
}

 

service

public List<MenuResponse> findMenuList() {
    List<Menu> menuEntity = menuRepository.findAll();
    return menuMapper.toDtoList(menuEntity);
}

mapper

package com.example.admin_project.menu.mapper;

import com.example.admin_project.menu.dto.MenuResponse;
import com.example.admin_project.menu.entity.Menu;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;

import java.util.List;

@Mapper(componentModel = "spring") // (1)
public interface MenuMapper {

    @Mapping(source = "parent.id", target = "parentId") // (2)
    @Mapping(target = "children", qualifiedByName = "mapChildren") // (3)
    MenuResponse toDto(Menu menu);

    List<MenuResponse> toDtoList(List<Menu> menuList);

    // 자식 메뉴를 재귀적으로 변환
    @Named("mapChildren") // (4)
    default List<MenuResponse> mapChildren(List<Menu> children) {
        return children != null ? toDtoList(children) : null;
    }
}

 

주석 설명
(1) Mapper 구현체를 Spring Bean으로 등록하기 위한 설정
 -> MapStruct은 컴파일 시 자동으로 MenuMapperImpl라는 구현 클래스를 생성
(2) Menu 엔티티 객체의 parent.id 값을 MenuResponse DTO의 parentId 필드로 매핑
(3) 자식 메뉴 필드를 mapChildren 메서드를 사용해 재귀적으로 매핑
-> qualifiedByName = "mapChildren"는 @Named("mapChildren")로 지정된 메서드를 사용하겠다는 의미입니다.
(4) MapStruct가 사용할 수 있도록 mapChildren 메서드를 이름으로 지정

 

@Mapping(source = "children", target = "children")
MenuResponse toDto(Menu menu);
  • source: 원본 객체(예: Menu 엔티티)의 필드 이름
  • target: 대상 객체(예: MenuResponse DTO)의 필드 이름

 

toDtoList()만 쓰는데 왜 toDto()가 필요??

 -> toDtoList()는 내부적으로 리스트 요소 하나하나에 toDto()를 호출하기 때문

 

(전체 흐름)

1. toDto(Menu) 호출

  • 상위 메뉴 하나를 변환 하기 위해 toDto(Menu)가 호출됨

2. MapStruct가 children 필드에 접근시

  • @Mapping(target = "children", qualifiedByName = "mapChildren") 설정 덕분에
  • Menu의 children 필드는 자동 매핑하지 않고, 위에 설정에 맞는 mapChildren() 메서드를 호출

3. mapChildren() 호출

@Named("mapChildren")
default List<MenuResponse> mapChildren(List<Menu> children) {
    return children != null ? toDtoList(children) : null;
}
  • children이 null이 아니면 toDtoList()로 변환

4. toDtoList()가 리스트 반복

  • 리스트 안의 각각의 Menu를 toDto()로 다시 변환함 (재귀 호출)
  • 이 안에서도 또 children이 있다면?
  • 다시 mapChildren() 호출됨

 

'어드민 프로젝트' 카테고리의 다른 글

어드민 프로젝트 로그 파일 읽어서 DB저장(스케줄러) - 3  (0) 2025.07.09
어드민 프로젝트 사용자 행동 로그파일 저장(AOP) - 2  (0) 2025.06.06
프로젝트 하면서 찾아본 내용  (0) 2025.05.16
'어드민 프로젝트' 카테고리의 다른 글
  • 어드민 프로젝트 로그 파일 읽어서 DB저장(스케줄러) - 3
  • 어드민 프로젝트 사용자 행동 로그파일 저장(AOP) - 2
  • 프로젝트 하면서 찾아본 내용
꾸준2
꾸준2
  • 꾸준2
    꾸준2
    꾸준2
  • 전체
    오늘
    어제
    • 분류 전체보기 (157)
      • 복습 프로젝트 (3)
      • 어드민 프로젝트 (4)
      • 프로젝트 리팩토링 (4)
      • Database (0)
      • Java Library (2)
      • Java (4)
      • Java(JVM) (1)
      • 자바 문제 (13)
        • 이론 (6)
        • 실습 (7)
      • IDE (2)
        • IntelliJ (2)
      • 인강 (13)
        • SpringBoot(JPA활용1) (0)
        • 자바(기본편) (6)
        • 자바(중급1편) (3)
        • 자바(중급2편) (1)
        • 자바 ORM 표준 JPA 프로그래밍 - 기본편 (3)
      • Network (2)
      • Node (3)
      • CS (0)
      • amCharts4 (5)
      • 오류 모음 (4)
        • 리눅스 (1)
      • 기타지식 (2)
      • 자주 사용하는 기능 (4)
      • Vue (11)
      • Javascript (13)
      • Javascript-메서드 (3)
      • CSS (6)
      • 라이브러리 (4)
      • 자료구조 (11)
      • 알고리즘 (4)
      • Vue-프로젝트 (20)
      • Vue-bitcoin프로젝트 (6)
      • 블로그클론 프로젝트 (11)
      • 면접 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
꾸준2
어드민 프로젝트 mapstruct 적용 - 1
상단으로

티스토리툴바