주로 엔티티와 DTO간의 데이터 전달에서, 빌더 모델매퍼와 같은 방식이 있다는 것은 알고 있었지만 정확한 개념이나 사용방법을 잘 익히지 못하고 있었기에 사용을 미루고 있었다. 제일 기본적인
public void toEntity(Member member) {
this.memberName = member.getMemberName();
this.memberPhone = member.getMemberPhone();
}
과 같은 방식으로 데이터를 주고 받았었다.
프로젝트 상에서 큰 문제를 일으키지 않았고, 잘 작동했기 때문에 이를 바꾸려고 하지는 않았었다. 그러나 엔티티의 컬럼들이 많아지고 넣어야 하는 테이터들이 증가하자 이렇게 사용하기에는 귀찮고 더 편한 방법을 찾기 시작했다.
그렇게 찾게된게 1. @Builder 2. Modelmapper 이다. 각각의 장단점과 사용방법에 대해 알아보려 한다.
빌더패턴에는 1. 점증적 생성자 패턴 2. 자바 빈즈 패턴 3. 빌더 패턴이 있다. 1번과 2번의 경우 코드량도 많고 가독성이 그렇게 좋지 않기 때문에 생략하도록 하겠다.
** 자바 빈즈 패턴
뒤에 잠깐 언급이 나와 설명하자면,
public class Member {
private String name;
private int age;
public Member() {}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
Member member = new Member(); // 선 객체 생성, 후 값 부여
member.setName("ABC");
member.setAge(22);
생성자에 매개변수가 많을 경우 빌더를 고려하면 좋다. 정보들은 자바빈즈패턴처럼 받지만, 데이터 일관성을 위해 정보들을 다 받은 후에 객체를 생성한다.
빌더 클래스를 직접 만드는 방법도 있지만 이것은 스킵...
롬복을 이용해서 사용하는 방법은 다음과 같다.
@Builder
public class Member{
private final String name;
private final int age;
}
Member member = Member.builder()
.name("ABC")
.age(22)
.build();
간단하게 생성이 가능하다.
우리가 엔티티에 빌더를 바로 적용해서 원하는 값을 넣을 수 있지만, RequestDto나 다른 Dto를 통해 값을 얻어올 경우 엔티티의 컬럼과 정확하게 일치하지 않을 경우가 많다. 이 경우의 빌더 사용법을 보자.
** RequestDto에서 name, age만 받아온다는 가정
Entity
public class Member {
private String name;
private int age;
private String house;
public void toEntity(RequestDto requestDto, String house) {
this.name = requestDto.getName();
this.age = requestDto.getAge();
this.house = house;
}
}
@Service
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
@Trnasactional
public void saveMember(RequestDto requestDto, String house) {
Member member = new Member();
member.toEntity(requestDto, house);
memberRepository.save(member);
}
}
public class Member {
private String name;
private int age;
private String house;
@Builder
public Member(RequestDto requestDto, String house) {
this.name = requestDto.getName();
this.age = requestDto.getAge();
this.house = house;
}
}
@Service
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
@Trnasactional
public void saveMember(RequestDto requestDto, String house) {
Member member = Member.builder()
.requestDto(requestDto)
.house(house)
.build();
memberRepository.save(member);
}
}
사실 빌더를 사용했을 때 코드상의 큰 차이점을 아직은 잘 모르겠다. 그래도 엔티티와 DTO의 데이터 전달 방법의 새로운 길을 찾은 것 같아 기분이 좋다.
모델매퍼와 같이 정리하려 했는데 나눠 정리하는게 가독성이 좋을 것 같아 이쯤에서 마무리하려 한다. 2부에서 모델매퍼를 정리해보겠다.
참고 1