SpringBoot ModelMapper 왜 사용하는가?

devdo·2022년 3월 20일
0

SpringBoot

목록 보기
18/35
post-thumbnail

Entity - Dto mapping converting을 위해 자주 사용됩니다.

map() 메서드 하나만으로 Entity - Dto 간 여러 필드가 매핑이 돼서 아주 편리합니다.


build.gradle

    // https://mvnrepository.com/artifact/org.modelmapper/modelmapper
    implementation group: 'org.modelmapper', name: 'modelmapper', version: '2.3.9'

MapperConfig
ModelMapper를 빈으로 등록해주어야 합니다.

@Configuration
public class MapperConfig {

    @Bean
    public ModelMapper modelMapper() {
        return new ModelMapper();
    }
}

Entity, Dto

@Data를 쓰면 오류가 납니다. Entity, Dto 에는 @Data 대신에 @Getter @Setter로 써주어야 합니다.
그리고 모든 필드가 맞아야 한다는... 이거때문에 ModelMapper를 못쓸 것 같은데...


@Getter
@Setter

ServiceImpl 안 mapToDto, mapToEntity 메서드에 활용

private final ModelMapper mapper;	// 생성자 주입

mapToDto

private CommentDto mapToDto(Comment comment) {
/*        return CommentDto.builder()
                .id(comment.getId())
                .name(comment.getName())
                .email(comment.getEmail())
                .body(comment.getBody())
                .build();
                .build();*/
        return mapper.map(comment, CommentDto.class);
    }

mapToEntity

private Comment mapToEntity(CommentDto commentDto) {
/*            return Comment.builder()
                    .id(commentDto.getId())
                    .name(commentDto.getName())
                    .email(commentDto.getEmail())
                    .body(commentDto.getBody())
                    .build();
                    .build();*/
        return mapper.map(commentDto, Comment.class);
    }

또는 Dto, Entity 내부 메서드로

ItemImgDto

@Data
public class ItemImgDto {

    private Long id;

    private String imgName;
    private String oriImgName;
    private String imgUrl;
    private String regImgYn;

	// new 연산자 사용, 객체 생성
    private static ModelMapper modelMapper = new ModelMapper();

    public static ItemImgDto of(ItemImg itemImg) {
        return modelMapper.map(itemImg, ItemImgDto.class);
    }

}

Item

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@ToString
@Table(name = "items")
public class Item extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "item_id", nullable = false)
    private Long id;            // 상품코드

    @Column(nullable = false, length = 50)
    private String name;    // 상품이름

    @Column(nullable = false)
    private int price;          // 상품가격

    @Column(nullable = false)
    private int stock;          // 재고수량

    @Enumerated(EnumType.STRING)
    @Column(name = "status")
    private ItemSellStatus status;

    @Lob        // 255 길이의 문자를 저장하고 싶을 때 지정
    @Column(nullable = false)
    private String description; // 상품 상세 설명

    @Builder
    public Item(Long id, String name, int price, int stock, ItemSellStatus status, String description) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.stock = stock;
        this.status = status;
        this.description = description;
    }

    public void updateItem(ItemFormDto itemFormDto) {
        this.name = itemFormDto.getName();
        this.price = itemFormDto.getPrice();
        this.stock = itemFormDto.getStock();
        this.status = itemFormDto.getStatus();
        this.description = itemFormDto.getDescription();
    }

    private static ModelMapper modelMapper = new ModelMapper();

    public static Item of(ItemFormDto itemFormDto) {
        return modelMapper.map(itemFormDto, Item.class);
    }
}

ModelMapper 문제점

ModelMapper

는 Entity에서도 @Setter가 필요하다...
안 그러면 넣지 않은 값들이 null처리가 된다.

-> 해결책
Access level 이 public 인 것을 볼 수 있다.
이를 private 레벨로 바꿔주면 setter 없이도 필드명이 같을 때 자동 매핑처리될 수 있다.

@Bean
public ModelMapper modelMapper() {
	ModelMapper modelMapper = new ModelMapper();
    modelMapper.getConfiguration()    				.setFieldAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PRIVATE)
.setFieldMatchingEnabled(true);

	retuen modelMapper; 
}

참고) https://lokie.tistory.com/26

MapStruct를 써라?

https://dev-splin.github.io/spring/Spring-ModelMapper,MapStruct/



참고

profile
배운 것을 기록합니다.

0개의 댓글