1. MapStruct 란?
- 자바 bean 유형 간 (ex. DTO ↔ Entity간) 의 매핑코드를 자동으로 생성하는 라이브러리
- 컴파일 시점에 매핑 코드 자동 생성 → 런타임에서 안정성 보장
- 반복되는 객체 매핑에서 발생할 수 있는 오류 줄일 수 있음
2. 사용 방법
2-1. dependency (의존성) 추가
- build.gradle
dependencies {
...
implementation 'org.mapstruct:mapstruct:1.5.3.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final'
...
}
📌 주의
Lombok 라이브러리에 먼저 의존성 추가가 되어 있어야 함
MapStruct : Lombok의 getter, setter, builder 를 이용하여 생성됨 ⇒ Lombok보다 먼저 의존성이 선언된 경우 실행 불가!
2-2. DTO, Entity 코드
// Entity 클래스
@Entity
public class User {
private Long id;
private String name;
private String email;
private String password;
}
// User DTO 클래스
public class UserDto {
private String name;
private String email;
}
2-3. Interface 생성
2-3-1. Interface 생성 (일대일)
@Mapper(componenetModel = "spring") // componentModel 생략 가능
public interface UserMapper {
// 매퍼 클래스에서 해당 인터페이스 (UserMapper)를 찾게 해줌
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
UserDto toDto(User user);
User toEntity(UserDto userDto);
}
⇒ 컬럼명이 다른경우 직접 지정 → @Mapping(source=”source 필드명”, target=”target 필드명”)
- MapStruct 라이브러리가 UserMapper 인터페이스를 기반으로 아래의 구현 클래스를 자동 생성함
import org.springframework.stereotype.Component;
@Component
public class UserMapperImpl implements UserMapper {
@Override
public UserDto toDto(User user) {
if (user == null) {
return null;
}
UserDto userDto = new UserDto();
userDto.setName(user.getName());
userDto.setEmail(user.getEmail());
return userDto;
}
@Override
public User toEntity(UserDto userDto) {
if (userDto == null) {
return null;
}
User user = new User();
user.setName(userDto.getName());
user.setEmail(userDto.getEmail());
return user;
}
}
⇒ 해당 구현체는 빌드 시 build/classes/java/main에 매핑 인터페이스가 위치한 곳에 만들어짐!
2-3-2. Interface 생성 (다대일)
- 여러 객체를 하나의 객체에 매핑하는 경우
public interface MessageMapper {
MessageMapper INSTANCE = Mappers.getMapper(MessageMapper.class);
// PageDto, RequestDto -> MessageServiceDto 매핑
@Mapping(source="pageDto.pageIndex", target="pageIdx")
@Mapping(source="pageDto.pageCount", target="pageCnt")
MessageServiceDto toMessageServiceDto(PageDto pageDto, RequestDto requestDto);
}
2-4. 매핑 사용
- 사용 예시 코드
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
@Autowired
private UserMapper userMapper; // UserMapper를 주입받음
public UserDto getUser(Long id) {
User user = userRepository.findById(id);
return userMapper.toDto(user); // UserMapper 사용 -> DTO로 변환
}
public void saveUser(UserDto userDto) {
User user = userMapper.toEntity(userDto); // UserMapper 사용 -> 엔티티로 변환
userRepository.save(user);
}
}