[Java] dto와 entity 변환하기 -2 <ObjectMapper>

개발개발·2021년 6월 10일
0

지난 글에 이어서 적는다. builder방식으로 작성하면서 코드량이 많아서 불편했다. 해결하기 위해서 찾은 방법은 ObjectMapper다.

프론트앤드에서 백앤드로 전달하는 데이터도 스프링에서 받을때는 ObjectMapper를 통해서 변환된다. (종종 오류메세지에서 본기억이 난다.)

  • usersDto
@Data
@NoArgsConstructor
public class UsersDto {

    private int id;
    private String token;
    private String password;
    private Date regDate;
    private String email;

    @Builder
    public UsersDto(int id, String token, String password, Date regDate, String email) {
        this.id = id;
        this.token = token;
        this.password = password;
        this.regDate = regDate;
        this.email = email;
    }
// 1편에서 사용한 방식
public static UsersEntity converter(UsersDto usersDto){
    	if(usersDto == null) return null;
        return UsersEntity.builder()
                .token(usersDto.getToken())
                .password(usersDto.getPassword())
                .regDate(usersDto.getRegDate())
                .email(usersDto.getEmail())
                .build();
    }
    
   public static UsersEntity mapper(UsersDto usersDto){
        if(usersDto==null) return null;
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
        
        return objectMapper.convertValue(usersDto,UsersEntity.class);
    }

한결 간단해졌다. ObjectMapper에서 직렬화와 역직렬화 설정을 해주고 convertValue(변환을 당할? 객체,변환하려는 클래스 ) 메소드를 사용하면 된다.

직렬화 설정은 빈값은 직렬화하지 않는 것이고 역직렬화 설정은 대상 클래스에 선언된 변수가 아닌 경우 변환시키지 않는 것이다.

코드가 짧아진것처럼 보이지 않을 수 있지만 변수가 많을수록 줄어드는 코드량이 많다.

장점

  • 코드량이 많이 줄어들었다.

단점

  • 여전히 모든 dto나 entity에 설정해줘야 한다.
  • 외래키로 묶여있는 다른 entity나 dto는 변환되지 않는다.

예시로 만든 entity를 보면 관계를 맺는 테이블이 없다. 토이프로젝트로 만들더라도 사용자 정보를 담은 entity가 관계맺어지지 않는 경우는 거의 없을것 같다.

  • testDto
@Data
public class TestDto {
	private int i1=0;
	private String s1="";
	private float f1 = 0;
 
    @Builder
    public TestDto(int i1, String s1,, float f1,) {
        this.i1 = i1;
        this.s1 = s1;
        this.f1 = f1;
        
    }
}
  • usersDto -> 외래키 추가
@Data
@NoArgsConstructor
public class UsersDto {

    private int id;
    private String token;
    private String password;
    private Date regDate;
    private String email;
    
    private TestDto testDto;

    @Builder
    public UsersDto(int id, String token, String password, Date regDate, String email,TestDto testDto) {
        this.id = id;
        this.token = token;
        this.password = password;
        this.regDate = regDate;
        this.email = email;
        this.testDto = testDto;
    }
// 1편에서 사용한 방식
public static UsersEntity converter(UsersDto usersDto){
        // OneToOne관계의 테이블
        TestDto testDto = usersDto.getTestEntity();
    	TestEntity testEntity = testDto.builder()
                .i1(testDto.getI1())
                .s1(testDto.getS1())
                .f1(testDto.getF1())
                .build();
                
        return UsersEntity.builder()
                .token(usersDto.getToken())
                .password(usersDto.getPassword())
                .regDate(usersDto.getRegDate())
                .email(usersDto.getEmail())
                .testDto(testDto)
                .build();
    }
    
   public static UsersEntity mapper(UsersDto usersDto){
        if(usersDto==null) return null;
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
        UsersEntity usersEntity = objectMapper.convertValue(usersDto,UsersEntity.class);
        TestDto testDto = objectMapper.convertValue(testDto, TestEntity);
        usersEntity.setTestDto(testDto);
        return usersEntity;
    }

위와같이 외래키가 늘어날수록 코드량은 점점 많아져서 @Builder 방식은 포기했다. 2번째 방식도 매번 반복되는 코드가 생겨서 귀찮음을 해결해보고자 제네릭메소드를 사용해보게 되었다.

profile
청포도루이보스민트티

0개의 댓글