지난 글에 이어서 적는다. builder방식으로 작성하면서 코드량이 많아서 불편했다. 해결하기 위해서 찾은 방법은 ObjectMapper다.
프론트앤드에서 백앤드로 전달하는 데이터도 스프링에서 받을때는 ObjectMapper를 통해서 변환된다. (종종 오류메세지에서 본기억이 난다.)
@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(변환을 당할? 객체,변환하려는 클래스 ) 메소드를 사용하면 된다.
직렬화 설정은 빈값은 직렬화하지 않는 것이고 역직렬화 설정은 대상 클래스에 선언된 변수가 아닌 경우 변환시키지 않는 것이다.
코드가 짧아진것처럼 보이지 않을 수 있지만 변수가 많을수록 줄어드는 코드량이 많다.
장점
단점
예시로 만든 entity를 보면 관계를 맺는 테이블이 없다. 토이프로젝트로 만들더라도 사용자 정보를 담은 entity가 관계맺어지지 않는 경우는 거의 없을것 같다.
@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;
}
}
@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번째 방식도 매번 반복되는 코드가 생겨서 귀찮음을 해결해보고자 제네릭메소드를 사용해보게 되었다.