SlideShare uma empresa Scribd logo
1 de 14
Baixar para ler offline
MapStruct
소스 : https://github.com/hyomee/JAVABASIC
Content
1. pom.xml 설정
2. 동일 이름 매핑
3. Spring과 CDI ( Contexts and Dependency Injection )
4. 다른 이름 매핑
5. 여러 객체를 하나로
6. 리스트 객체
7. 자식 매핑
8. 기존 인스턴스 객체 update
9. 타입 매핑, 기본값, NULL, 표현식
10. 매핑 전. 후 처리 및 Collection Mapping
11. 정책
소스 : https://github.com/hyomee/JAVABASIC
1. 기본
- <dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.0.Final</version>
</dependency>
MapStruct는 java Bean 간의 매핑을 구현을 단순화하는 코드 생성기
Interface를 생성 한 후 컴파일을 하면 자동으로 구현채를 생성 함.
- mapstruct-processor 구성
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.1.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
@Mapper
public interface SimpleSourceToTargetMapper {
SimpleSourceToTargetMapper SIMPLE_SOURCE_TO_TARGET_MAPPER = Mappers.getMapper(SimpleSourceToTargetMapper.class);
SimpleTargetDTO sourceDTOToTargetDTO(SimpleSourceDTO simpleSourceDTO);
SimpleSourceDTO targetDTOToSoreceDTO(SimpleTargetDTO simpleTargetDTO);
}
@Generated(
value = "org.mapstruct.ap.MappingProcessor“)
@Component
public class SimpleSourceToTargetMapperImpl implements SimpleSourceToTargetMapper {
@Override
public SimpleTargetDTO sourceDTOToTargetDTO(SimpleSourceDTO simpleSourceDTO) {
if ( simpleSourceDTO == null ) {
return null;
}
SimpleTargetDTO simpleTargetDTO = new SimpleTargetDTO();
simpleTargetDTO.setCustNo( simpleSourceDTO.getCustNo() );
simpleTargetDTO.setCustNm( simpleSourceDTO.getCustNm() );
return simpleTargetDTO;
}
@Override
public SimpleSourceDTO targetDTOToSoreceDTO(SimpleTargetDTO simpleTargetDTO) {
if ( simpleTargetDTO == null ) {
return null;
}
SimpleSourceDTO simpleSourceDTO = new SimpleSourceDTO();
simpleSourceDTO.setCustNo( simpleTargetDTO.getCustNo() );
simpleSourceDTO.setCustNm( simpleTargetDTO.getCustNm() );
return simpleSourceDTO;
}
}
mvn clean install ( compile )
2. 동일 이름 매핑
@Mapper
public interface SimpleSourceToTargetMapper {
SimpleSourceToTargetMapper SIMPLE_SOURCE_TO_TARGET_MAPPER = Mappers.getMapper(SimpleSourceToTargetMapper.class);
SimpleTargetDTO sourceDTOToTargetDTO(SimpleSourceDTO simpleSourceDTO);
}
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2021-01-04T22:33:37+0900",
comments = "version: 1.4.1.Final, compiler: javac, environment: Java 11.0.2 (Oracle Corporation)"
)
@Component
public class SimpleSourceToTargetMapperImpl implements SimpleSourceToTargetMapper {
@Override
public SimpleTargetDTO sourceDTOToTargetDTO(SimpleSourceDTO simpleSourceDTO) {
if ( simpleSourceDTO == null ) {
return null;
}
SimpleTargetDTO simpleTargetDTO = new SimpleTargetDTO();
simpleTargetDTO.setCustNo( simpleSourceDTO.getCustNo() );
simpleTargetDTO.setCustNm( simpleSourceDTO.getCustNm() );
return simpleTargetDTO;
}}
mvn clean install ( compile )
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class SimpleSourceDTO {
private String custNo;
private String custNm;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class SimpleTargetDTO {
private String custNo;
private String custNm;
}
@Test
void contextLoads() {
SimpleSourceDTO simpleSourceDTO = SimpleSourceDTO.of("홍길동", "A0001");
SimpleTargetDTO simpleTargetDTO = SimpleSourceToTargetMapper.SIMPLE_SOURCE_TO_TARGET_MAPPER.sourceDTOToTargetDTO(simpleSourceDTO);
assertEquals(simpleSourceDTO.getCustNm(), simpleTargetDTO.getCustNm());
assertEquals(simpleSourceDTO.getCustNo(), simpleTargetDTO.getCustNo());
}
매핑
3. Spring과 CDI
- Spring 사용 :: @Mapper(componentModel = "spring")
- Spring 미사용 :: @Mapper(componentModel = " cdi ")
MapStruct 의존성 주입
프로그램 스레드 이름 : main :: Start
프로그램 스레드 이름 : main :: End
프로그램 스레드 이름 : threadB :: add ...
프로그램 스레드 이름 : threadA :: add ...
프로그램 스레드 이름 : ThreadC :: add ...
프로그램 스레드 이름 : ThreadC :: 20 까지의 합은 : 210
프로그램 스레드 이름 : threadB :: 20 까지의 합은 : 210
프로그램 스레드 이름 : threadA :: 20 까지의 합은 : 210
프로그램 스레드 이름 : main :: Start
프로그램 스레드 이름 : main :: End
프로그램 스레드 이름 : threadE :: add ...
프로그램 스레드 이름 : threadD :: add ...
프로그램 스레드 이름 : threadD :: 20 까지의 합은 : 210
프로그램 스레드 이름 : threadE :: 20 까지의 합은 : 210
@Mapper(componentModel = "spring")
public interface SimpleToTargetInjection {
SimpleTargetDTO sourceToTarget(SimpleSourceDTO simpleSourceDTO);
SimpleSourceDTO targetToSorece(SimpleTargetDTO simpleTargetDTO);
}
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2021-01-04T23:21:52+0900",
comments = "version: 1.4.1.Final, compiler: javac, environment: Java 11.0.2 (Oracle Corporation)"
)
@Component
public class SimpleToTargetInjectionImpl implements SimpleToTargetInjection {
@Override
public SimpleTargetDTO sourceToTarget(SimpleSourceDTO simpleSourceDTO) {
if ( simpleSourceDTO == null ) {
return null;
}
SimpleTargetDTO simpleTargetDTO = new SimpleTargetDTO();
simpleTargetDTO.setCustNo( simpleSourceDTO.getCustNo() );
simpleTargetDTO.setCustNm( simpleSourceDTO.getCustNm() );
return simpleTargetDTO;
}
……….
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class SimpleSourceDTO {
private String custNo;
private String custNm;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class SimpleTargetDTO {
private String custNo;
private String custNm;
}
@Autowired
private SimpleToTargetInjection simpleToTargetInjection ;
@Test
void contextLoads() {
SimpleSourceDTO simpleSourceDTO = SimpleSourceDTO.of("홍길동", "A0001");
SimpleTargetDTO simpleTargetDTO = simpleToTargetInjection.sourceToTarget(simpleSourceDTO);
assertEquals(simpleSourceDTO.getCustNm(), simpleTargetDTO.getCustNm());
assertEquals(simpleSourceDTO.getCustNo(), simpleTargetDTO.getCustNo());
}
4. 다른 동일 이름 매핑
mvn clean install ( compile )
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class SimpleSourceDTO {
private String custNo;
private String custNm;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class SimpleDifferentTargetDTO {
private String custNumber;
private String custNm;
private String ages;
}
@Mapper(componentModel = "spring")
public interface DiffrentMapStruct {
@Mappings({
@Mapping(target="custNumber", source = "custNo")
})
SimpleDifferentTargetDTO simpleToDifferent(SimpleSourceDTO simpleSourceDTO);
} 매핑
@Autowired
private DiffrentMapStruct diffrentMapStruct ;
@Test
void contextLoads() {
SimpleSourceDTO simpleSourceDTO = SimpleSourceDTO.of("홍길동", "A0001");
SimpleDifferentTargetDTO simpleDifferentTargetDTO = diffrentMapStruct.simpleToDifferent(simpleSourceDTO);
assertEquals(simpleSourceDTO.getCustNm(), simpleDifferentTargetDTO.getCustNm());
assertEquals(simpleSourceDTO.getCustNo(), simpleDifferentTargetDTO.getCustNumber());
}
@Generated(
value = "org.mapstruct.ap.MappingProcessor"
)
@Component
public class DiffrentMapStructImpl implements DiffrentMapStruct {
@Override
public SimpleDifferentTargetDTO simpleToDifferent(SimpleSourceDTO simpleSourceDTO) {
if ( simpleSourceDTO == null ) {
return null;
}
SimpleDifferentTargetDTO simpleDifferentTargetDTO = new SimpleDifferentTargetDTO();
simpleDifferentTargetDTO.setCustNumber( simpleSourceDTO.getCustNo() );
simpleDifferentTargetDTO.setCustNm( simpleSourceDTO.getCustNm() );
return simpleDifferentTargetDTO;
}
}
5. 여러 객체를 하나로
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class UserDTO {
private String userNo;
private String userNm;
private String ages;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class AddressDTO {
private String userNo;
private String postNo;
private String address;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class UserAddressDTO {
private String userNo;
private String userNm;
private String nai;
private String address;
}
@Mapper(componentModel = "spring")
public interface Composer {
@Mapping(target = "nai", source = "userDTO.ages")
@Mapping(target = "userNo", source = "userDTO.userNo")
UserAddressDTO toUserAddress(UserDTO userDTO, AddressDTO
addressDTO);
}
@Generated(
value = "org.mapstruct.ap.MappingProcessor"
)
@Component
public class ComposerImpl implements Composer {
@Override
public UserAddressDTO toUserAddress(UserDTO userDTO, AddressDTO addressDTO) {
if ( userDTO == null && addressDTO == null ) {
return null;
}
UserAddressDTO userAddressDTO = new UserAddressDTO();
if ( userDTO != null ) {
userAddressDTO.setNai( userDTO.getAges() );
userAddressDTO.setUserNo( userDTO.getUserNo() );
userAddressDTO.setUserNm( userDTO.getUserNm() );
}
if ( addressDTO != null ) {
userAddressDTO.setAddress( addressDTO.getAddress() );
}
return userAddressDTO;
}
}
** 같은 이름을 재외 한 다른 이름의 필드를 @Mapping을 사용해서 정의
source는 객체.필드를 사용 하여 정확히 표시 함
=> 표시 하지 않으면 빌드 오류 발생
6. 리스트 객체
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class UserAddDTO {
private String userNo;
private String userNm;
private String ages;
private List<AddressDTO> addressDTOList;
private List<MemberDTO> memberDTOList;
} @Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class MemberDTO {
private String userNo;
private String memberNo;
private String memberNm;
private String ages;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class AddressDTO {
private String userNo;
private String postNo;
private String address;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class TargetUserAddDTO {
private String userNo;
private String userNm;
private String ages;
private List<AddressDTO> addressDTOS;
private List<MemberDTO> memberDTOList;
}
@Mapper(componentModel = "spring")
public interface usertToTarget {
@Mapping(target="addressDTOS", source = "addressDTOList")
TargetUserAddDTO toDto(UserAddDTO userAddDTO);
}
@Generated(
value = "org.mapstruct.ap.MappingProcessor")
@Component
public class usertToTargetImpl implements usertToTarget {
@Override
public TargetUserAddDTO toDto(UserAddDTO userAddDTO) {
if ( userAddDTO == null ) {
return null;
}
TargetUserAddDTO targetUserAddDTO = new TargetUserAddDTO();
List<AddressDTO> list = userAddDTO.getAddressDTOList();
if ( list != null ) {
targetUserAddDTO.setAddressDTOS( new ArrayList<AddressDTO>( list ) );
}
targetUserAddDTO.setUserNo( userAddDTO.getUserNo() );
targetUserAddDTO.setUserNm( userAddDTO.getUserNm() );
targetUserAddDTO.setAges( userAddDTO.getAges() );
List<MemberDTO> list1 = userAddDTO.getMemberDTOList();
if ( list1 != null ) {
targetUserAddDTO.setMemberDTOList( new ArrayList<MemberDTO>( list1 ) );
}
return targetUserAddDTO;
}
}
동일이름 자동 매핑
다른 이름
7. 자식 매핑
@Generated(
value = "org.mapstruct.ap.MappingProcessor")
@Component
public class UserParentMapperImpl implements UserParentMapper {
@Autowired
private AddressChildMapper addressChildMapper;
@Override
public UserParentDTO toDto(UserParent userParent) {
if ( userParent == null ) {
return null;
}
UserParentDTO userParentDTO = new UserParentDTO();
userParentDTO.setAddressChildDTOList( addressChildListToAddressChildDTOList( userParent.getAddressChildList() ) );
userParentDTO.setUserNo( userParent.getUserNo() );
userParentDTO.setUserNm( userParent.getUserNm() );
return userParentDTO;
}
protected List<AddressChildDTO> addressChildListToAddressChildDTOList(List<AddressChild> list) {
if ( list == null ) {
return null;
}
List<AddressChildDTO> list1 = new ArrayList<AddressChildDTO>( list.size() );
for ( AddressChild addressChild : list ) {
list1.add( addressChildMapper.toDto( addressChild ) );
}
return list1;
}
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class AddressChild {
private String userNo;
private String adderssNo;
private String address;
}
public class UserParent {
private String userNo;
private String userNm;
private List<AddressChild> addressChildList;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class UserParentDTO {
private String userNo;
private String userNm;
private List<AddressChildDTO>
addressChildDTOList;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class AddressChildDTO {
private String userNo;
private String adderssNo;
private String address;
}
@Mapper(componentModel = "spring", uses = {AddressChildMapper.class})
public interface UserParentMapper {
@Mapping(target = "addressChildDTOList", source = "userParent.addressChildList")
UserParentDTO toDto(UserParent userParent);
}
8. 기존 인스턴스 update
@Generated(
value = "org.mapstruct.ap.MappingProcessor")
@Component
public class UserParentMapperImpl implements UserParentMapper {
@Autowired
private AddressChildMapper addressChildMapper;
@Override
public void updateUserParentDto(UserParent userParent, UserParentDTO userParentDTO) {
if ( userParent == null ) {
return;
}
if ( userParentDTO.getAddressChildDTOList() != null ) {
List<AddressChildDTO> list = addressChildListToAddressChildDTOList( userParent.getAddressChildList() );
if ( list != null ) {
userParentDTO.getAddressChildDTOList().clear();
userParentDTO.getAddressChildDTOList().addAll( list );
}
else {
userParentDTO.setAddressChildDTOList( null );
}
}
else {
List<AddressChildDTO> list = addressChildListToAddressChildDTOList( userParent.getAddressChildList() );
if ( list != null ) {
userParentDTO.setAddressChildDTOList( list );
}
}
userParentDTO.setUserNo( userParent.getUserNo() );
userParentDTO.setUserNm( userParent.getUserNm() );
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class AddressChild {
private String userNo;
private String adderssNo;
private String address;
}
public class UserParent {
private String userNo;
private String userNm;
private List<AddressChild> addressChildList;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class UserParentDTO {
private String userNo;
private String userNm;
private List<AddressChildDTO>
addressChildDTOList;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class AddressChildDTO {
private String userNo;
private String adderssNo;
private String address;
}
@Mapper(componentModel = "spring", uses = {AddressChildMapper.class})
public interface UserParentMapper {
@Mapping(target = "addressChildDTOList", source = "userParent.addressChildList")
void updateUserParentDto(UserParent userParent,
@MappingTarget UserParentDTO userParentDTO);
}
9. 타입 매핑, 기본값, NULL, 표현식
@Mapper(componentModel = "string",
// ERROR, IGNORE, WARN 정책
unmappedTargetPolicy = ReportingPolicy.ERROR,
// Source가 null이거나 혹은 Source의 특정 필드가 null인 경우
nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL,
imports = {LocalDateTime.class, UUID.class})
public interface DataTypeMap {
@Mapping(target="id", constant = "-1L")
@Mapping(target="userId", expression = "java(UUID.randomUUID().toString())")
@Mapping(target="userNm", source = "userNm", defaultValue = "이름")
@Mapping(target="birthday", source = "birthday", dateFormat = "dd-MM-yyyy HH:mm:ss")
@Mapping(target="pay", source = "pay", numberFormat = "$#.00")
@Mapping(target="currentDate", source = "currentDate",
defaultExpression = "java(LocalDateTime.now())")
// 특정 필드는 매핑되지 않길 원한다면 @Mapping 어노테이션에 ignore = true 속성
@Mapping(target="desc", source = "desc", ignore = true)
UserTypeDTO toDto(UserType userType);
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class UserType {
private long id;
private String userId;
private String userNm;
private Date birthday;
private String pay;
private LocalDateTime currentDate;
private String desc;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(staticName = "of")
public class UserTypeDTO {
private long id;
private String userId ; // defaultExpression
private String userNm;
private String birthday; // dateFormat
private long pay; // numberFormat
private LocalDateTime currentDate;
private String desc;
}
@Generated(
value = "org.mapstruct.ap.MappingProcessor"
)
public class DataTypeMapImpl implements DataTypeMap {
@Override
public UserTypeDTO toDto(UserType userType) {
if ( userType == null ) {
return null;
}
UserTypeDTO userTypeDTO = new UserTypeDTO();
if ( userType.getUserNm() != null ) {
userTypeDTO.setUserNm( userType.getUserNm() );
}
else {
userTypeDTO.setUserNm( "이름" );
}
if ( userType.getBirthday() != null ) {
userTypeDTO.setBirthday( new SimpleDateFormat( "dd-MM-yyyy HH:mm:ss" ).format( userType.getBirthday() ) );
}
try {
if ( userType.getPay() != null ) {
userTypeDTO.setPay( new DecimalFormat( "$#.00" ).parse( userType.getPay() ).longValue() );
}
}
catch ( ParseException e ) {
throw new RuntimeException( e );
}
if ( userType.getCurrentDate() != null ) {
userTypeDTO.setCurrentDate( userType.getCurrentDate() );
}
else {
userTypeDTO.setCurrentDate( LocalDateTime.now() );
}
userTypeDTO.setId( -1L );
userTypeDTO.setUserId( UUID.randomUUID().toString() );
return userTypeDTO;
}
}
10. 매핑 전. 후 처리 및 Collection Mapping
@Mapper(uses = {PatientMapper.class}, componentModel = "spring")
public abstract class DoctorCustomMapper {
@BeforeMapping
protected void validate(Doctor doctor) {
if(doctor.getPatientList() == null){
doctor.setPatientList(new ArrayList<>());
}
}
@AfterMapping
protected void updateResult(@MappingTarget DoctorDto doctorDto) {
doctorDto.setName(doctorDto.getName().toUpperCase());
doctorDto.setDegree(doctorDto.getDegree().toUpperCase());
doctorDto.setSpecialization(doctorDto.getSpecialization().toUpperCase());
}
@Mapping(source = "doctor.patientList", target = "patientDtoList")
@Mapping(source = "doctor.specialty", target = "specialization")
public abstract DoctorDto toDoctorDto(Doctor doctor);
}
https://www.baeldung.com/java-mapstruct-mapping-collections
@Mapper
public interface EmployeeMapper {
List<EmployeeDTO> map(List<Employee> employees);
}
@Mapper
public interface EmployeeMapper {
Set<EmployeeDTO> map(Set<Employee> employees);
}
11. 정책
정책 값 설명
unmappedSourcePolicy
IGNORE(default),
WARN,
ERROR
Source의 필드가 Target에 매핑되지 않을 때 정책이다.
예, ERROR로 설정하면 매핑 시 Source.aField가 사용되지 않는다면 컴파일 오류가 발생시킨다.
unmappedTargetPolicy
IGNORE,
WARN(default),
ERROR
Target의 필드가 매핑되지 않을 때 정책이다.
예, ERROR로 설정하면 매핑 시 Target.aField에 값이 매핑되지 않는다면 컴파일 오류가 발생시킨다.
typeConversionPolicy
IGNORE(default),
WARN,
ERROR
타입 변환 시 유실이 발생할 수 있을 때 정책이다.
예, ERROR로 설정하면 long에서 int로 값을 넘길 때 값에 유실이 발생할 수 있다. 이런 경우에 컴파일 오류를 발생
시킨다.
전략 값 설명
nullValueMappingStrategy
RETURN_NULL(default),
RETURN_DEFAULT
Source가 null일 때 정책이다.
nullValuePropertyMappingStrategy
SET_TO_NULL(default),
SET_TO_DEFAULT,
IGNORE
Source의 필드가 null일 때 정책이다.
www.iabacus.co.kr
Tel. 82-2-2109-5400
Fax. 82-2-6442-5409
THANKS

Mais conteúdo relacionado

Mais procurados

Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5 Wildan Maulana
 
Twitter Author Prediction from Tweets using Bayesian Network
Twitter Author Prediction from Tweets using Bayesian NetworkTwitter Author Prediction from Tweets using Bayesian Network
Twitter Author Prediction from Tweets using Bayesian NetworkHendy Irawan
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6Dmitry Soshnikov
 
Reactive Access to MongoDB from Scala
Reactive Access to MongoDB from ScalaReactive Access to MongoDB from Scala
Reactive Access to MongoDB from ScalaHermann Hueck
 
Python client api
Python client apiPython client api
Python client apidreampuf
 
JEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistJEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistAnton Arhipov
 
Gae icc fall2011
Gae icc fall2011Gae icc fall2011
Gae icc fall2011Juan Gomez
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)James Titcumb
 
Google Guava for cleaner code
Google Guava for cleaner codeGoogle Guava for cleaner code
Google Guava for cleaner codeMite Mitreski
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6Fiyaz Hasan
 
Catch a spider monkey
Catch a spider monkeyCatch a spider monkey
Catch a spider monkeyChengHui Weng
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleAnton Arhipov
 
Python Performance 101
Python Performance 101Python Performance 101
Python Performance 101Ankur Gupta
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)David de Boer
 
Session 40 : SAGA Overview and Introduction
Session 40 : SAGA Overview and Introduction Session 40 : SAGA Overview and Introduction
Session 40 : SAGA Overview and Introduction ISSGC Summer School
 

Mais procurados (20)

Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5
 
Twitter Author Prediction from Tweets using Bayesian Network
Twitter Author Prediction from Tweets using Bayesian NetworkTwitter Author Prediction from Tweets using Bayesian Network
Twitter Author Prediction from Tweets using Bayesian Network
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
 
Sbaw091006
Sbaw091006Sbaw091006
Sbaw091006
 
Reactive Access to MongoDB from Scala
Reactive Access to MongoDB from ScalaReactive Access to MongoDB from Scala
Reactive Access to MongoDB from Scala
 
Python client api
Python client apiPython client api
Python client api
 
srgoc
srgocsrgoc
srgoc
 
Pragmatic sbt
Pragmatic sbtPragmatic sbt
Pragmatic sbt
 
JEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with JavassistJEEConf 2017 - Having fun with Javassist
JEEConf 2017 - Having fun with Javassist
 
Gae icc fall2011
Gae icc fall2011Gae icc fall2011
Gae icc fall2011
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
Google Guava for cleaner code
Google Guava for cleaner codeGoogle Guava for cleaner code
Google Guava for cleaner code
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6
 
Catch a spider monkey
Catch a spider monkeyCatch a spider monkey
Catch a spider monkey
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassle
 
Python Performance 101
Python Performance 101Python Performance 101
Python Performance 101
 
Kotlin Generation
Kotlin GenerationKotlin Generation
Kotlin Generation
 
Java File
Java FileJava File
Java File
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
 
Session 40 : SAGA Overview and Introduction
Session 40 : SAGA Overview and Introduction Session 40 : SAGA Overview and Introduction
Session 40 : SAGA Overview and Introduction
 

Semelhante a MapStruct Guide for Mapping Java Objects

CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmersAlexander Varwijk
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)Jose Manuel Pereira Garcia
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Tsuyoshi Yamamoto
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionChristian Panadero
 
The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]Nilhcem
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureAlexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureC.T.Co
 
Non Conventional Android Programming (English)
Non Conventional Android Programming (English)Non Conventional Android Programming (English)
Non Conventional Android Programming (English)Davide Cerbo
 
Non Conventional Android Programming En
Non Conventional Android Programming EnNon Conventional Android Programming En
Non Conventional Android Programming Enguest9bcef2f
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensionserwanl
 
Powerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatisPowerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatissimonetripodi
 
Webinar: Building Your First App with MongoDB and Java
Webinar: Building Your First App with MongoDB and JavaWebinar: Building Your First App with MongoDB and Java
Webinar: Building Your First App with MongoDB and JavaMongoDB
 

Semelhante a MapStruct Guide for Mapping Java Objects (20)

CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmers
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
mobl
moblmobl
mobl
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca edition
 
The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Non Conventional Android Programming (English)
Non Conventional Android Programming (English)Non Conventional Android Programming (English)
Non Conventional Android Programming (English)
 
Non Conventional Android Programming En
Non Conventional Android Programming EnNon Conventional Android Programming En
Non Conventional Android Programming En
 
ExSchema
ExSchemaExSchema
ExSchema
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensions
 
Powerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatisPowerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatis
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
 
Android - Api & Debugging in Android
Android - Api & Debugging in AndroidAndroid - Api & Debugging in Android
Android - Api & Debugging in Android
 
Webinar: Building Your First App with MongoDB and Java
Webinar: Building Your First App with MongoDB and JavaWebinar: Building Your First App with MongoDB and Java
Webinar: Building Your First App with MongoDB and Java
 

Mais de Hyosang Hong

Mais de Hyosang Hong (20)

MSA_기초자료.pdf
MSA_기초자료.pdfMSA_기초자료.pdf
MSA_기초자료.pdf
 
Java 변수자료형
Java 변수자료형Java 변수자료형
Java 변수자료형
 
Java 연산자
Java 연산자Java 연산자
Java 연산자
 
Java lambda
Java lambdaJava lambda
Java lambda
 
Java inner class
Java inner classJava inner class
Java inner class
 
Java generic
Java genericJava generic
Java generic
 
Java 기초
Java 기초Java 기초
Java 기초
 
Java extends
Java extendsJava extends
Java extends
 
Java 제어
Java 제어Java 제어
Java 제어
 
Java collection
Java collectionJava collection
Java collection
 
Java class
Java classJava class
Java class
 
Spring 교육 자료
Spring 교육 자료Spring 교육 자료
Spring 교육 자료
 
Kafka 자료 v0.1
Kafka 자료 v0.1Kafka 자료 v0.1
Kafka 자료 v0.1
 
Jpa 쿼리 포함 자료
Jpa 쿼리 포함 자료Jpa 쿼리 포함 자료
Jpa 쿼리 포함 자료
 
Java 이해하기 쉬운 코드 20210405
Java 이해하기 쉬운 코드 20210405Java 이해하기 쉬운 코드 20210405
Java 이해하기 쉬운 코드 20210405
 
Java 유지보수 가능한 개발 원칙
Java 유지보수 가능한 개발 원칙Java 유지보수 가능한 개발 원칙
Java 유지보수 가능한 개발 원칙
 
Enum
EnumEnum
Enum
 
Java stream v0.1
Java stream v0.1Java stream v0.1
Java stream v0.1
 
Spring 교육 자료
Spring 교육 자료Spring 교육 자료
Spring 교육 자료
 
Map struct
Map structMap struct
Map struct
 

Último

1029-Danh muc Sach Giao Khoa khoi 6.pdf
1029-Danh muc Sach Giao Khoa khoi  6.pdf1029-Danh muc Sach Giao Khoa khoi  6.pdf
1029-Danh muc Sach Giao Khoa khoi 6.pdfQucHHunhnh
 
Z Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphZ Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphThiyagu K
 
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...Sapna Thakur
 
Sanyam Choudhary Chemistry practical.pdf
Sanyam Choudhary Chemistry practical.pdfSanyam Choudhary Chemistry practical.pdf
Sanyam Choudhary Chemistry practical.pdfsanyamsingh5019
 
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptxPOINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptxSayali Powar
 
The byproduct of sericulture in different industries.pptx
The byproduct of sericulture in different industries.pptxThe byproduct of sericulture in different industries.pptx
The byproduct of sericulture in different industries.pptxShobhayan Kirtania
 
Web & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdfWeb & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdfJayanti Pande
 
1029 - Danh muc Sach Giao Khoa 10 . pdf
1029 -  Danh muc Sach Giao Khoa 10 . pdf1029 -  Danh muc Sach Giao Khoa 10 . pdf
1029 - Danh muc Sach Giao Khoa 10 . pdfQucHHunhnh
 
Introduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsIntroduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsTechSoup
 
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...fonyou31
 
mini mental status format.docx
mini    mental       status     format.docxmini    mental       status     format.docx
mini mental status format.docxPoojaSen20
 
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Sapana Sha
 
CARE OF CHILD IN INCUBATOR..........pptx
CARE OF CHILD IN INCUBATOR..........pptxCARE OF CHILD IN INCUBATOR..........pptx
CARE OF CHILD IN INCUBATOR..........pptxGaneshChakor2
 
microwave assisted reaction. General introduction
microwave assisted reaction. General introductionmicrowave assisted reaction. General introduction
microwave assisted reaction. General introductionMaksud Ahmed
 
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...EduSkills OECD
 
APM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across SectorsAPM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across SectorsAssociation for Project Management
 
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Krashi Coaching
 

Último (20)

1029-Danh muc Sach Giao Khoa khoi 6.pdf
1029-Danh muc Sach Giao Khoa khoi  6.pdf1029-Danh muc Sach Giao Khoa khoi  6.pdf
1029-Danh muc Sach Giao Khoa khoi 6.pdf
 
Z Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphZ Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot Graph
 
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
 
Sanyam Choudhary Chemistry practical.pdf
Sanyam Choudhary Chemistry practical.pdfSanyam Choudhary Chemistry practical.pdf
Sanyam Choudhary Chemistry practical.pdf
 
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptxPOINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
 
The byproduct of sericulture in different industries.pptx
The byproduct of sericulture in different industries.pptxThe byproduct of sericulture in different industries.pptx
The byproduct of sericulture in different industries.pptx
 
Web & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdfWeb & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdf
 
Advance Mobile Application Development class 07
Advance Mobile Application Development class 07Advance Mobile Application Development class 07
Advance Mobile Application Development class 07
 
1029 - Danh muc Sach Giao Khoa 10 . pdf
1029 -  Danh muc Sach Giao Khoa 10 . pdf1029 -  Danh muc Sach Giao Khoa 10 . pdf
1029 - Danh muc Sach Giao Khoa 10 . pdf
 
Introduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsIntroduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The Basics
 
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
Ecosystem Interactions Class Discussion Presentation in Blue Green Lined Styl...
 
mini mental status format.docx
mini    mental       status     format.docxmini    mental       status     format.docx
mini mental status format.docx
 
Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"
Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"
Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"
 
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
 
CARE OF CHILD IN INCUBATOR..........pptx
CARE OF CHILD IN INCUBATOR..........pptxCARE OF CHILD IN INCUBATOR..........pptx
CARE OF CHILD IN INCUBATOR..........pptx
 
microwave assisted reaction. General introduction
microwave assisted reaction. General introductionmicrowave assisted reaction. General introduction
microwave assisted reaction. General introduction
 
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
Presentation by Andreas Schleicher Tackling the School Absenteeism Crisis 30 ...
 
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptxINDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
 
APM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across SectorsAPM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across Sectors
 
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
 

MapStruct Guide for Mapping Java Objects

  • 2. Content 1. pom.xml 설정 2. 동일 이름 매핑 3. Spring과 CDI ( Contexts and Dependency Injection ) 4. 다른 이름 매핑 5. 여러 객체를 하나로 6. 리스트 객체 7. 자식 매핑 8. 기존 인스턴스 객체 update 9. 타입 매핑, 기본값, NULL, 표현식 10. 매핑 전. 후 처리 및 Collection Mapping 11. 정책 소스 : https://github.com/hyomee/JAVABASIC
  • 3. 1. 기본 - <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.4.0.Final</version> </dependency> MapStruct는 java Bean 간의 매핑을 구현을 단순화하는 코드 생성기 Interface를 생성 한 후 컴파일을 하면 자동으로 구현채를 생성 함. - mapstruct-processor 구성 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <source>1.8</source> <target>1.8</target> <annotationProcessorPaths> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.3.1.Final</version> </path> </annotationProcessorPaths> </configuration> </plugin> @Mapper public interface SimpleSourceToTargetMapper { SimpleSourceToTargetMapper SIMPLE_SOURCE_TO_TARGET_MAPPER = Mappers.getMapper(SimpleSourceToTargetMapper.class); SimpleTargetDTO sourceDTOToTargetDTO(SimpleSourceDTO simpleSourceDTO); SimpleSourceDTO targetDTOToSoreceDTO(SimpleTargetDTO simpleTargetDTO); } @Generated( value = "org.mapstruct.ap.MappingProcessor“) @Component public class SimpleSourceToTargetMapperImpl implements SimpleSourceToTargetMapper { @Override public SimpleTargetDTO sourceDTOToTargetDTO(SimpleSourceDTO simpleSourceDTO) { if ( simpleSourceDTO == null ) { return null; } SimpleTargetDTO simpleTargetDTO = new SimpleTargetDTO(); simpleTargetDTO.setCustNo( simpleSourceDTO.getCustNo() ); simpleTargetDTO.setCustNm( simpleSourceDTO.getCustNm() ); return simpleTargetDTO; } @Override public SimpleSourceDTO targetDTOToSoreceDTO(SimpleTargetDTO simpleTargetDTO) { if ( simpleTargetDTO == null ) { return null; } SimpleSourceDTO simpleSourceDTO = new SimpleSourceDTO(); simpleSourceDTO.setCustNo( simpleTargetDTO.getCustNo() ); simpleSourceDTO.setCustNm( simpleTargetDTO.getCustNm() ); return simpleSourceDTO; } } mvn clean install ( compile )
  • 4. 2. 동일 이름 매핑 @Mapper public interface SimpleSourceToTargetMapper { SimpleSourceToTargetMapper SIMPLE_SOURCE_TO_TARGET_MAPPER = Mappers.getMapper(SimpleSourceToTargetMapper.class); SimpleTargetDTO sourceDTOToTargetDTO(SimpleSourceDTO simpleSourceDTO); } @Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2021-01-04T22:33:37+0900", comments = "version: 1.4.1.Final, compiler: javac, environment: Java 11.0.2 (Oracle Corporation)" ) @Component public class SimpleSourceToTargetMapperImpl implements SimpleSourceToTargetMapper { @Override public SimpleTargetDTO sourceDTOToTargetDTO(SimpleSourceDTO simpleSourceDTO) { if ( simpleSourceDTO == null ) { return null; } SimpleTargetDTO simpleTargetDTO = new SimpleTargetDTO(); simpleTargetDTO.setCustNo( simpleSourceDTO.getCustNo() ); simpleTargetDTO.setCustNm( simpleSourceDTO.getCustNm() ); return simpleTargetDTO; }} mvn clean install ( compile ) @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class SimpleSourceDTO { private String custNo; private String custNm; } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class SimpleTargetDTO { private String custNo; private String custNm; } @Test void contextLoads() { SimpleSourceDTO simpleSourceDTO = SimpleSourceDTO.of("홍길동", "A0001"); SimpleTargetDTO simpleTargetDTO = SimpleSourceToTargetMapper.SIMPLE_SOURCE_TO_TARGET_MAPPER.sourceDTOToTargetDTO(simpleSourceDTO); assertEquals(simpleSourceDTO.getCustNm(), simpleTargetDTO.getCustNm()); assertEquals(simpleSourceDTO.getCustNo(), simpleTargetDTO.getCustNo()); } 매핑
  • 5. 3. Spring과 CDI - Spring 사용 :: @Mapper(componentModel = "spring") - Spring 미사용 :: @Mapper(componentModel = " cdi ") MapStruct 의존성 주입 프로그램 스레드 이름 : main :: Start 프로그램 스레드 이름 : main :: End 프로그램 스레드 이름 : threadB :: add ... 프로그램 스레드 이름 : threadA :: add ... 프로그램 스레드 이름 : ThreadC :: add ... 프로그램 스레드 이름 : ThreadC :: 20 까지의 합은 : 210 프로그램 스레드 이름 : threadB :: 20 까지의 합은 : 210 프로그램 스레드 이름 : threadA :: 20 까지의 합은 : 210 프로그램 스레드 이름 : main :: Start 프로그램 스레드 이름 : main :: End 프로그램 스레드 이름 : threadE :: add ... 프로그램 스레드 이름 : threadD :: add ... 프로그램 스레드 이름 : threadD :: 20 까지의 합은 : 210 프로그램 스레드 이름 : threadE :: 20 까지의 합은 : 210 @Mapper(componentModel = "spring") public interface SimpleToTargetInjection { SimpleTargetDTO sourceToTarget(SimpleSourceDTO simpleSourceDTO); SimpleSourceDTO targetToSorece(SimpleTargetDTO simpleTargetDTO); } @Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2021-01-04T23:21:52+0900", comments = "version: 1.4.1.Final, compiler: javac, environment: Java 11.0.2 (Oracle Corporation)" ) @Component public class SimpleToTargetInjectionImpl implements SimpleToTargetInjection { @Override public SimpleTargetDTO sourceToTarget(SimpleSourceDTO simpleSourceDTO) { if ( simpleSourceDTO == null ) { return null; } SimpleTargetDTO simpleTargetDTO = new SimpleTargetDTO(); simpleTargetDTO.setCustNo( simpleSourceDTO.getCustNo() ); simpleTargetDTO.setCustNm( simpleSourceDTO.getCustNm() ); return simpleTargetDTO; } ………. } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class SimpleSourceDTO { private String custNo; private String custNm; } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class SimpleTargetDTO { private String custNo; private String custNm; } @Autowired private SimpleToTargetInjection simpleToTargetInjection ; @Test void contextLoads() { SimpleSourceDTO simpleSourceDTO = SimpleSourceDTO.of("홍길동", "A0001"); SimpleTargetDTO simpleTargetDTO = simpleToTargetInjection.sourceToTarget(simpleSourceDTO); assertEquals(simpleSourceDTO.getCustNm(), simpleTargetDTO.getCustNm()); assertEquals(simpleSourceDTO.getCustNo(), simpleTargetDTO.getCustNo()); }
  • 6. 4. 다른 동일 이름 매핑 mvn clean install ( compile ) @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class SimpleSourceDTO { private String custNo; private String custNm; } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class SimpleDifferentTargetDTO { private String custNumber; private String custNm; private String ages; } @Mapper(componentModel = "spring") public interface DiffrentMapStruct { @Mappings({ @Mapping(target="custNumber", source = "custNo") }) SimpleDifferentTargetDTO simpleToDifferent(SimpleSourceDTO simpleSourceDTO); } 매핑 @Autowired private DiffrentMapStruct diffrentMapStruct ; @Test void contextLoads() { SimpleSourceDTO simpleSourceDTO = SimpleSourceDTO.of("홍길동", "A0001"); SimpleDifferentTargetDTO simpleDifferentTargetDTO = diffrentMapStruct.simpleToDifferent(simpleSourceDTO); assertEquals(simpleSourceDTO.getCustNm(), simpleDifferentTargetDTO.getCustNm()); assertEquals(simpleSourceDTO.getCustNo(), simpleDifferentTargetDTO.getCustNumber()); } @Generated( value = "org.mapstruct.ap.MappingProcessor" ) @Component public class DiffrentMapStructImpl implements DiffrentMapStruct { @Override public SimpleDifferentTargetDTO simpleToDifferent(SimpleSourceDTO simpleSourceDTO) { if ( simpleSourceDTO == null ) { return null; } SimpleDifferentTargetDTO simpleDifferentTargetDTO = new SimpleDifferentTargetDTO(); simpleDifferentTargetDTO.setCustNumber( simpleSourceDTO.getCustNo() ); simpleDifferentTargetDTO.setCustNm( simpleSourceDTO.getCustNm() ); return simpleDifferentTargetDTO; } }
  • 7. 5. 여러 객체를 하나로 @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class UserDTO { private String userNo; private String userNm; private String ages; } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class AddressDTO { private String userNo; private String postNo; private String address; } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class UserAddressDTO { private String userNo; private String userNm; private String nai; private String address; } @Mapper(componentModel = "spring") public interface Composer { @Mapping(target = "nai", source = "userDTO.ages") @Mapping(target = "userNo", source = "userDTO.userNo") UserAddressDTO toUserAddress(UserDTO userDTO, AddressDTO addressDTO); } @Generated( value = "org.mapstruct.ap.MappingProcessor" ) @Component public class ComposerImpl implements Composer { @Override public UserAddressDTO toUserAddress(UserDTO userDTO, AddressDTO addressDTO) { if ( userDTO == null && addressDTO == null ) { return null; } UserAddressDTO userAddressDTO = new UserAddressDTO(); if ( userDTO != null ) { userAddressDTO.setNai( userDTO.getAges() ); userAddressDTO.setUserNo( userDTO.getUserNo() ); userAddressDTO.setUserNm( userDTO.getUserNm() ); } if ( addressDTO != null ) { userAddressDTO.setAddress( addressDTO.getAddress() ); } return userAddressDTO; } } ** 같은 이름을 재외 한 다른 이름의 필드를 @Mapping을 사용해서 정의 source는 객체.필드를 사용 하여 정확히 표시 함 => 표시 하지 않으면 빌드 오류 발생
  • 8. 6. 리스트 객체 @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class UserAddDTO { private String userNo; private String userNm; private String ages; private List<AddressDTO> addressDTOList; private List<MemberDTO> memberDTOList; } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class MemberDTO { private String userNo; private String memberNo; private String memberNm; private String ages; } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class AddressDTO { private String userNo; private String postNo; private String address; } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class TargetUserAddDTO { private String userNo; private String userNm; private String ages; private List<AddressDTO> addressDTOS; private List<MemberDTO> memberDTOList; } @Mapper(componentModel = "spring") public interface usertToTarget { @Mapping(target="addressDTOS", source = "addressDTOList") TargetUserAddDTO toDto(UserAddDTO userAddDTO); } @Generated( value = "org.mapstruct.ap.MappingProcessor") @Component public class usertToTargetImpl implements usertToTarget { @Override public TargetUserAddDTO toDto(UserAddDTO userAddDTO) { if ( userAddDTO == null ) { return null; } TargetUserAddDTO targetUserAddDTO = new TargetUserAddDTO(); List<AddressDTO> list = userAddDTO.getAddressDTOList(); if ( list != null ) { targetUserAddDTO.setAddressDTOS( new ArrayList<AddressDTO>( list ) ); } targetUserAddDTO.setUserNo( userAddDTO.getUserNo() ); targetUserAddDTO.setUserNm( userAddDTO.getUserNm() ); targetUserAddDTO.setAges( userAddDTO.getAges() ); List<MemberDTO> list1 = userAddDTO.getMemberDTOList(); if ( list1 != null ) { targetUserAddDTO.setMemberDTOList( new ArrayList<MemberDTO>( list1 ) ); } return targetUserAddDTO; } } 동일이름 자동 매핑 다른 이름
  • 9. 7. 자식 매핑 @Generated( value = "org.mapstruct.ap.MappingProcessor") @Component public class UserParentMapperImpl implements UserParentMapper { @Autowired private AddressChildMapper addressChildMapper; @Override public UserParentDTO toDto(UserParent userParent) { if ( userParent == null ) { return null; } UserParentDTO userParentDTO = new UserParentDTO(); userParentDTO.setAddressChildDTOList( addressChildListToAddressChildDTOList( userParent.getAddressChildList() ) ); userParentDTO.setUserNo( userParent.getUserNo() ); userParentDTO.setUserNm( userParent.getUserNm() ); return userParentDTO; } protected List<AddressChildDTO> addressChildListToAddressChildDTOList(List<AddressChild> list) { if ( list == null ) { return null; } List<AddressChildDTO> list1 = new ArrayList<AddressChildDTO>( list.size() ); for ( AddressChild addressChild : list ) { list1.add( addressChildMapper.toDto( addressChild ) ); } return list1; } } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class AddressChild { private String userNo; private String adderssNo; private String address; } public class UserParent { private String userNo; private String userNm; private List<AddressChild> addressChildList; } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class UserParentDTO { private String userNo; private String userNm; private List<AddressChildDTO> addressChildDTOList; } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class AddressChildDTO { private String userNo; private String adderssNo; private String address; } @Mapper(componentModel = "spring", uses = {AddressChildMapper.class}) public interface UserParentMapper { @Mapping(target = "addressChildDTOList", source = "userParent.addressChildList") UserParentDTO toDto(UserParent userParent); }
  • 10. 8. 기존 인스턴스 update @Generated( value = "org.mapstruct.ap.MappingProcessor") @Component public class UserParentMapperImpl implements UserParentMapper { @Autowired private AddressChildMapper addressChildMapper; @Override public void updateUserParentDto(UserParent userParent, UserParentDTO userParentDTO) { if ( userParent == null ) { return; } if ( userParentDTO.getAddressChildDTOList() != null ) { List<AddressChildDTO> list = addressChildListToAddressChildDTOList( userParent.getAddressChildList() ); if ( list != null ) { userParentDTO.getAddressChildDTOList().clear(); userParentDTO.getAddressChildDTOList().addAll( list ); } else { userParentDTO.setAddressChildDTOList( null ); } } else { List<AddressChildDTO> list = addressChildListToAddressChildDTOList( userParent.getAddressChildList() ); if ( list != null ) { userParentDTO.setAddressChildDTOList( list ); } } userParentDTO.setUserNo( userParent.getUserNo() ); userParentDTO.setUserNm( userParent.getUserNm() ); } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class AddressChild { private String userNo; private String adderssNo; private String address; } public class UserParent { private String userNo; private String userNm; private List<AddressChild> addressChildList; } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class UserParentDTO { private String userNo; private String userNm; private List<AddressChildDTO> addressChildDTOList; } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class AddressChildDTO { private String userNo; private String adderssNo; private String address; } @Mapper(componentModel = "spring", uses = {AddressChildMapper.class}) public interface UserParentMapper { @Mapping(target = "addressChildDTOList", source = "userParent.addressChildList") void updateUserParentDto(UserParent userParent, @MappingTarget UserParentDTO userParentDTO); }
  • 11. 9. 타입 매핑, 기본값, NULL, 표현식 @Mapper(componentModel = "string", // ERROR, IGNORE, WARN 정책 unmappedTargetPolicy = ReportingPolicy.ERROR, // Source가 null이거나 혹은 Source의 특정 필드가 null인 경우 nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL, imports = {LocalDateTime.class, UUID.class}) public interface DataTypeMap { @Mapping(target="id", constant = "-1L") @Mapping(target="userId", expression = "java(UUID.randomUUID().toString())") @Mapping(target="userNm", source = "userNm", defaultValue = "이름") @Mapping(target="birthday", source = "birthday", dateFormat = "dd-MM-yyyy HH:mm:ss") @Mapping(target="pay", source = "pay", numberFormat = "$#.00") @Mapping(target="currentDate", source = "currentDate", defaultExpression = "java(LocalDateTime.now())") // 특정 필드는 매핑되지 않길 원한다면 @Mapping 어노테이션에 ignore = true 속성 @Mapping(target="desc", source = "desc", ignore = true) UserTypeDTO toDto(UserType userType); } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class UserType { private long id; private String userId; private String userNm; private Date birthday; private String pay; private LocalDateTime currentDate; private String desc; } @Getter @Setter @NoArgsConstructor @AllArgsConstructor(staticName = "of") public class UserTypeDTO { private long id; private String userId ; // defaultExpression private String userNm; private String birthday; // dateFormat private long pay; // numberFormat private LocalDateTime currentDate; private String desc; } @Generated( value = "org.mapstruct.ap.MappingProcessor" ) public class DataTypeMapImpl implements DataTypeMap { @Override public UserTypeDTO toDto(UserType userType) { if ( userType == null ) { return null; } UserTypeDTO userTypeDTO = new UserTypeDTO(); if ( userType.getUserNm() != null ) { userTypeDTO.setUserNm( userType.getUserNm() ); } else { userTypeDTO.setUserNm( "이름" ); } if ( userType.getBirthday() != null ) { userTypeDTO.setBirthday( new SimpleDateFormat( "dd-MM-yyyy HH:mm:ss" ).format( userType.getBirthday() ) ); } try { if ( userType.getPay() != null ) { userTypeDTO.setPay( new DecimalFormat( "$#.00" ).parse( userType.getPay() ).longValue() ); } } catch ( ParseException e ) { throw new RuntimeException( e ); } if ( userType.getCurrentDate() != null ) { userTypeDTO.setCurrentDate( userType.getCurrentDate() ); } else { userTypeDTO.setCurrentDate( LocalDateTime.now() ); } userTypeDTO.setId( -1L ); userTypeDTO.setUserId( UUID.randomUUID().toString() ); return userTypeDTO; } }
  • 12. 10. 매핑 전. 후 처리 및 Collection Mapping @Mapper(uses = {PatientMapper.class}, componentModel = "spring") public abstract class DoctorCustomMapper { @BeforeMapping protected void validate(Doctor doctor) { if(doctor.getPatientList() == null){ doctor.setPatientList(new ArrayList<>()); } } @AfterMapping protected void updateResult(@MappingTarget DoctorDto doctorDto) { doctorDto.setName(doctorDto.getName().toUpperCase()); doctorDto.setDegree(doctorDto.getDegree().toUpperCase()); doctorDto.setSpecialization(doctorDto.getSpecialization().toUpperCase()); } @Mapping(source = "doctor.patientList", target = "patientDtoList") @Mapping(source = "doctor.specialty", target = "specialization") public abstract DoctorDto toDoctorDto(Doctor doctor); } https://www.baeldung.com/java-mapstruct-mapping-collections @Mapper public interface EmployeeMapper { List<EmployeeDTO> map(List<Employee> employees); } @Mapper public interface EmployeeMapper { Set<EmployeeDTO> map(Set<Employee> employees); }
  • 13. 11. 정책 정책 값 설명 unmappedSourcePolicy IGNORE(default), WARN, ERROR Source의 필드가 Target에 매핑되지 않을 때 정책이다. 예, ERROR로 설정하면 매핑 시 Source.aField가 사용되지 않는다면 컴파일 오류가 발생시킨다. unmappedTargetPolicy IGNORE, WARN(default), ERROR Target의 필드가 매핑되지 않을 때 정책이다. 예, ERROR로 설정하면 매핑 시 Target.aField에 값이 매핑되지 않는다면 컴파일 오류가 발생시킨다. typeConversionPolicy IGNORE(default), WARN, ERROR 타입 변환 시 유실이 발생할 수 있을 때 정책이다. 예, ERROR로 설정하면 long에서 int로 값을 넘길 때 값에 유실이 발생할 수 있다. 이런 경우에 컴파일 오류를 발생 시킨다. 전략 값 설명 nullValueMappingStrategy RETURN_NULL(default), RETURN_DEFAULT Source가 null일 때 정책이다. nullValuePropertyMappingStrategy SET_TO_NULL(default), SET_TO_DEFAULT, IGNORE Source의 필드가 null일 때 정책이다.