본문 바로가기
Language/Java

[Java] DTO <-> Entity 변환(ModelMapper & method & ModelMapper List 바인딩)

by lucas_owner 2022. 12. 22.

* 정답이 아닐수 있으며 제가 사용하는 방법들에 대해 설명할 예정입니다!

DTO <-> Entity 변환

Entity 와 DTO는 분리하여 사용하는것이 좋기 때문에 분리해서 사용하다 보면 

각 객체간에 어떻게 변환을 하는지에 대해서 의문점이 생길것이다. 

구글링을 조금만 하더라도 여러가지 방법들이 보이기 때문이다..!

 

1. DTO 내부 메서드로 값을 전달하는 방법.

2. Model Mapper 라이브러리를 사용하는 방법. 

3. JPA사용시 Repository에서 직접 조회하는 방법

 

이 글에서는 3번을 제외하고 설명 해볼 생각이다. 

 

- DTO, Entity 내부 편의 메서드 작성법 

- Model Mapper 단건 바인딩.

- 다건(List) 바인딩.  (Model Mapper List 바인딩.)

 

 

Entity <-> DTO 분리해야 하는 이유는 아래 링크에서 확인해보세요! 

https://lucas-owner.tistory.com/18

 

[Java] DAO, DTO, VO, Entity 란?

웹 개발을 하다 보면 DAO, DTO, VO, Entity라는 단어들을 많이 접하게 된다. 해당 개념을 잘 잡아놔야 협업시에 문제가 없을 것 같다. DAO - DAO란 Data Access Object 의 약자이며 이름 그대로 DB의 data에 접근

lucas-owner.tistory.com


DTO 내부에서 사용하는 방법.

 

DTO Class

Entity Class

 

- 위와 같이 두개의 클래스가 있을때 코드를 추가하여 Entity <-> DTO 로 변환을 해보겠다. 

 

- Entity 

- toEntity 메서드 추가.

- Test를 위해 @ToString 사용. 

package com.example.makeproject.board.domain;

import lombok.*;
import lombok.extern.slf4j.Slf4j;

import javax.persistence.*;

@Entity
@Table(name = "board_info")
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Slf4j
public class Board {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long boardId;   /*게시판 아이디*/
    private String title;   /*게시판 제목*/
    private String content; /*게시판 내용*/
    private String writer;  /*작성자*/

    public static Board toEntity(BoardDTO dto) {
        return Board.builder()
                .boardId(dto.getBoardId())
                .title(dto.getTitle())
                .content(dto.getContent())
                .writer(dto.getWriter())
                .build();
    }
}

- DTO 

- toDTO 추가 

package com.example.makeproject.board.domain;

import lombok.*;

@Getter
@Setter
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BoardDTO {

    private Long boardId;   /*게시판 아이디*/
    private String title;   /*게시판 제목*/
    private String content; /*게시판 내용*/
    private String writer;  /*작성자*/


    public static BoardDTO toDTO(Board entity) {
        return BoardDTO.builder()
                .boardId(entity.getBoardId())
                .title(entity.getTitle())
                .content(entity.getContent())
                .writer(entity.getWriter())
                .build();
    }

}

 

 

- Service 

 

- 결과 

- 의도 했던 대로 Entity <-> DTO 변환이 이루어졌다. 

- 해당 방법은 Entity 사용에 있어서 Setter 가 없어야 한다는 조건과, 다른 로직이 들어있으면 안된다는 것에 부합하기 때문에 

  꼭 필요한 경우가 아니면 사용하지 않는다!(Entity 사용의 좋은 전략을 의미)


Model Mapper 사용

- Model Mapper 라는 라이브러리를 사용하여 간단하게 변환 하는 방법이다. 

- 해당 라이브러리를 사용하려면 DTO, Entity 의 필드가 동일해야 에러가 발생하지 않는다. 

- 만약 데이터를 별도로 가공을 해야한다면 DTO Inner Class를 생성하여 사용하는것을 추천한다. 

 

1. Model Mapper 라이브러리 추가

implementation group: 'org.modelmapper', name: 'modelmapper', version: '2.3.8' // Model mapper

 

2. config 파일 생성

- Model Mapper 를 사용하기 위해서는 config 파일을 별도로 생성을 해주어야 한다. 

3.  Service 코드 작성

- model Mapper 를 사용하기 위해서 DI(Dependency Injection) 주입. 

- modelMapper.map 사용

  인자의 첫번째는 바꿀 객체, 두번째는 어떤 타입으로 변경할건지에 대한 객체이다. 

- 응용하면 순서만 바꾼채로 Entity <-> DTO 변환이 가능하다.

- 편의를 위해 toString 코드 작성!!!!!!!!

 

4. 결과

 

5. 다건(List) 바인딩.  (Model Mapper List 바인딩.)

- 위의 방법들은 List 타입으로 받는것이 아니기 때문에 List 타입은 어떻게 받는지 궁금할 것이다.... 

  코드의 살짝 변형만 주면 List 타입으로도 쉽게 받을 수 있다. 

 

- List 타입은 따로 코드를 작성하지 않으면 Conversion 에러가 발생한다. 

 

- List 바인딩 코드 

- List 바인딩 코드 예제

// Entity to DTO 바인딩

List<DTO> resultDTO = entity.stream()
                            .map(data -> modelMapper.map(data, DTO.class))
                            .collect(Collectors.toList());

- 결과

반응형

댓글