SlideShare a Scribd company logo
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

More Related Content

DOC
12. stl örnekler
karmuhtam
 
PDF
The Browser Environment - A Systems Programmer's Perspective
Eleanor McHugh
 
PDF
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
Eleanor McHugh
 
DOCX
PathOfMostResistance
Edward Cleveland
 
PDF
Go for the paranoid network programmer, 3rd edition
Eleanor McHugh
 
PDF
5. Ввод-вывод, доступ к файловой системе
DEVTYPE
 
PDF
Apache Commons - Don\'t re-invent the wheel
tcurdt
 
ODP
Scala 2 + 2 > 4
Emil Vladev
 
12. stl örnekler
karmuhtam
 
The Browser Environment - A Systems Programmer's Perspective
Eleanor McHugh
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
Eleanor McHugh
 
PathOfMostResistance
Edward Cleveland
 
Go for the paranoid network programmer, 3rd edition
Eleanor McHugh
 
5. Ввод-вывод, доступ к файловой системе
DEVTYPE
 
Apache Commons - Don\'t re-invent the wheel
tcurdt
 
Scala 2 + 2 > 4
Emil Vladev
 

What's hot (18)

PDF
Design Patterns in PHP5
Wildan Maulana
 
PPTX
Twitter Author Prediction from Tweets using Bayesian Network
Hendy Irawan
 
PDF
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
Dmitry Soshnikov
 
KEY
Sbaw091006
Atsushi Tadokoro
 
PDF
Python client api
dreampuf
 
DOCX
srgoc
Gaurav Singh
 
PDF
JEEConf 2017 - Having fun with Javassist
Anton Arhipov
 
KEY
Gae icc fall2011
Juan Gomez
 
PDF
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
James Titcumb
 
PDF
Google Guava for cleaner code
Mite Mitreski
 
PPTX
What’s new in C# 6
Fiyaz Hasan
 
PDF
Catch a spider monkey
ChengHui Weng
 
PDF
GeeCON 2017 - TestContainers. Integration testing without the hassle
Anton Arhipov
 
PDF
Python Performance 101
Ankur Gupta
 
PDF
Kotlin Generation
Minseo Chayabanjonglerd
 
PDF
Java File
Archita Misra
 
PDF
Being functional in PHP (DPC 2016)
David de Boer
 
PDF
Session 40 : SAGA Overview and Introduction
ISSGC Summer School
 
Design Patterns in PHP5
Wildan Maulana
 
Twitter Author Prediction from Tweets using Bayesian Network
Hendy Irawan
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
Dmitry Soshnikov
 
Sbaw091006
Atsushi Tadokoro
 
Python client api
dreampuf
 
JEEConf 2017 - Having fun with Javassist
Anton Arhipov
 
Gae icc fall2011
Juan Gomez
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
James Titcumb
 
Google Guava for cleaner code
Mite Mitreski
 
What’s new in C# 6
Fiyaz Hasan
 
Catch a spider monkey
ChengHui Weng
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
Anton Arhipov
 
Python Performance 101
Ankur Gupta
 
Kotlin Generation
Minseo Chayabanjonglerd
 
Java File
Archita Misra
 
Being functional in PHP (DPC 2016)
David de Boer
 
Session 40 : SAGA Overview and Introduction
ISSGC Summer School
 
Ad

Similar to Map struct (20)

KEY
CouchDB on Android
Sven Haiges
 
PDF
Multilingualism makes better programmers
Alexander Varwijk
 
PDF
Having Fun with Play
Clinton Dreisbach
 
PDF
From Legacy to Hexagonal (An Unexpected Android Journey)
Jose Manuel Pereira Garcia
 
KEY
Android workshop
Michael Galpin
 
PDF
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Tsuyoshi Yamamoto
 
PDF
mobl
zefhemel
 
PDF
My way to clean android - Android day salamanca edition
Christian Panadero
 
PDF
The 2016 Android Developer Toolbox [MOBILIZATION]
Nilhcem
 
PDF
Overview of Android Infrastructure
Alexey Buzdin
 
PDF
Overview of Android Infrastructure
C.T.Co
 
ODP
Non Conventional Android Programming En
guest9bcef2f
 
ODP
Non Conventional Android Programming (English)
Davide Cerbo
 
PPTX
ExSchema
jccastrejon
 
KEY
Paris js extensions
erwanl
 
PDF
Powerful persistence layer with Google Guice & MyBatis
simonetripodi
 
PDF
Vaadin7
Joonas Lehtinen
 
PPT
Play!ng with scala
Siarzh Miadzvedzeu
 
PPT
Android - Api & Debugging in Android
Vibrant Technologies & Computers
 
PDF
Webinar: Building Your First App with MongoDB and Java
MongoDB
 
CouchDB on Android
Sven Haiges
 
Multilingualism makes better programmers
Alexander Varwijk
 
Having Fun with Play
Clinton Dreisbach
 
From Legacy to Hexagonal (An Unexpected Android Journey)
Jose Manuel Pereira Garcia
 
Android workshop
Michael Galpin
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Tsuyoshi Yamamoto
 
mobl
zefhemel
 
My way to clean android - Android day salamanca edition
Christian Panadero
 
The 2016 Android Developer Toolbox [MOBILIZATION]
Nilhcem
 
Overview of Android Infrastructure
Alexey Buzdin
 
Overview of Android Infrastructure
C.T.Co
 
Non Conventional Android Programming En
guest9bcef2f
 
Non Conventional Android Programming (English)
Davide Cerbo
 
ExSchema
jccastrejon
 
Paris js extensions
erwanl
 
Powerful persistence layer with Google Guice & MyBatis
simonetripodi
 
Play!ng with scala
Siarzh Miadzvedzeu
 
Android - Api & Debugging in Android
Vibrant Technologies & Computers
 
Webinar: Building Your First App with MongoDB and Java
MongoDB
 
Ad

More from Hyosang Hong (20)

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

Recently uploaded (20)

PDF
Virat Kohli- the Pride of Indian cricket
kushpar147
 
PPTX
Dakar Framework Education For All- 2000(Act)
santoshmohalik1
 
DOCX
SAROCES Action-Plan FOR ARAL PROGRAM IN DEPED
Levenmartlacuna1
 
PDF
The-Invisible-Living-World-Beyond-Our-Naked-Eye chapter 2.pdf/8th science cur...
Sandeep Swamy
 
PPTX
family health care settings home visit - unit 6 - chn 1 - gnm 1st year.pptx
Priyanshu Anand
 
PPTX
How to Track Skills & Contracts Using Odoo 18 Employee
Celine George
 
DOCX
pgdei-UNIT -V Neurological Disorders & developmental disabilities
JELLA VISHNU DURGA PRASAD
 
PPTX
How to Manage Leads in Odoo 18 CRM - Odoo Slides
Celine George
 
PPTX
An introduction to Prepositions for beginners.pptx
drsiddhantnagine
 
PPTX
CONCEPT OF CHILD CARE. pptx
AneetaSharma15
 
PPTX
How to Apply for a Job From Odoo 18 Website
Celine George
 
PPTX
Applications of matrices In Real Life_20250724_091307_0000.pptx
gehlotkrish03
 
PPTX
Kanban Cards _ Mass Action in Odoo 18.2 - Odoo Slides
Celine George
 
PDF
Review of Related Literature & Studies.pdf
Thelma Villaflores
 
DOCX
Unit 5: Speech-language and swallowing disorders
JELLA VISHNU DURGA PRASAD
 
PPTX
Sonnet 130_ My Mistress’ Eyes Are Nothing Like the Sun By William Shakespear...
DhatriParmar
 
PPTX
A Smarter Way to Think About Choosing a College
Cyndy McDonald
 
PPTX
Software Engineering BSC DS UNIT 1 .pptx
Dr. Pallawi Bulakh
 
PPTX
Introduction to pediatric nursing in 5th Sem..pptx
AneetaSharma15
 
PPTX
BASICS IN COMPUTER APPLICATIONS - UNIT I
suganthim28
 
Virat Kohli- the Pride of Indian cricket
kushpar147
 
Dakar Framework Education For All- 2000(Act)
santoshmohalik1
 
SAROCES Action-Plan FOR ARAL PROGRAM IN DEPED
Levenmartlacuna1
 
The-Invisible-Living-World-Beyond-Our-Naked-Eye chapter 2.pdf/8th science cur...
Sandeep Swamy
 
family health care settings home visit - unit 6 - chn 1 - gnm 1st year.pptx
Priyanshu Anand
 
How to Track Skills & Contracts Using Odoo 18 Employee
Celine George
 
pgdei-UNIT -V Neurological Disorders & developmental disabilities
JELLA VISHNU DURGA PRASAD
 
How to Manage Leads in Odoo 18 CRM - Odoo Slides
Celine George
 
An introduction to Prepositions for beginners.pptx
drsiddhantnagine
 
CONCEPT OF CHILD CARE. pptx
AneetaSharma15
 
How to Apply for a Job From Odoo 18 Website
Celine George
 
Applications of matrices In Real Life_20250724_091307_0000.pptx
gehlotkrish03
 
Kanban Cards _ Mass Action in Odoo 18.2 - Odoo Slides
Celine George
 
Review of Related Literature & Studies.pdf
Thelma Villaflores
 
Unit 5: Speech-language and swallowing disorders
JELLA VISHNU DURGA PRASAD
 
Sonnet 130_ My Mistress’ Eyes Are Nothing Like the Sun By William Shakespear...
DhatriParmar
 
A Smarter Way to Think About Choosing a College
Cyndy McDonald
 
Software Engineering BSC DS UNIT 1 .pptx
Dr. Pallawi Bulakh
 
Introduction to pediatric nursing in 5th Sem..pptx
AneetaSharma15
 
BASICS IN COMPUTER APPLICATIONS - UNIT I
suganthim28
 

Map struct

  • 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일 때 정책이다.