
ูุฃุณุจุงุจ ู
ุนุฑููุฉ ุ ูุง ูู
ูู ููุฌูุฉ ุงูุฎูููุฉ ุฅุฑุฌุงุน ุงูุจูุงูุงุช ู
ู ุงูู
ุณุชูุฏุน ูู
ุง ูู. ุงูุฃูุซุฑ ุดูุฑุฉ - ูุง ุชุคุฎุฐ ุงูุชุจุนูุงุช ุงูุฃุณุงุณูุฉ ู
ู ุงููุงุนุฏุฉ ูู ุงูุดูู ุงูุฐู ูู
ูู ููุฌุจูุฉ ููู
ูุง. ููุง ูู
ููู ุฅุถุงูุฉ ุตุนูุจุงุช ูู ุชุญููู ุงูุชุนุฏุงุฏ (ุฅุฐุง ูุงูุช ุญููู ุงูุชุนุฏุงุฏ ุชุญุชูู ุนูู ู
ุนูู
ุงุช ุฅุถุงููุฉ) ุ ูุงูุนุฏูุฏ ู
ู ุงูุตุนูุจุงุช ุงูุฃุฎุฑู ุงููุงุดุฆุฉ ุนู ุงูุตุจ ุงูุชููุงุฆู ูููุชุงุจุฉ (ุฃู ุนุฏู
ุงููุฏุฑุฉ ุนูู ุฅููุงุกูุง ุชููุงุฆููุง). ูุฐุง ูุนูู ุงูุญุงุฌุฉ ุฅูู ุงุณุชุฎุฏุงู
ูุงุฆู ููู ุงูุจูุงูุงุช - DTO ุ ููู ุฃู
ุฑ ู
ูููู
ููู ู
ู ุงูุฎูู ูุงูุฃู
ุงู
.
ูู
ูู ุฅุฌุฑุงุก ุชุญููู ููุงู ุฅูู DTO ุจุนุฏุฉ ุทุฑู ู
ุฎุชููุฉ. ูู
ููู ุงุณุชุฎุฏุงู
ุงูู
ูุชุจุฉ ุ ูู
ููู (ุฅุฐุง ูุงู ุงูู
ุดุฑูุน ุตุบูุฑูุง) ุฅูุดุงุก ุดูุก ู
ุซู ูุฐุง:
@Component public class ItemMapperImpl implements ItemMapper { private final OrderRepository orderRepository; @Autowired public ItemMapperImpl(OrderRepository orderRepository) { this.orderRepository = orderRepository; } @Override public Item toEntity(ItemDto dto) { return new Item( dto.getId(), obtainOrder(dto.getOrderId()), dto.getArticle(), dto.getName(), dto.getDisplayName(), dto.getWeight(), dto.getCost(), dto.getEstimatedCost(), dto.getQuantity(), dto.getBarcode(), dto.getType() ); } @Override public ItemDto toDto(Item item) { return new ItemDto( item.getId(), obtainOrderId(item), item.getArticle(), item.getName(), item.getDisplayName(), item.getWeight(), item.getCost(), item.getEstimatedCost(), item.getQuantity(), item.getBarcode(), item.getType() ); } private Long obtainOrderId(Item item) { return Objects.nonNull(item.getOrder()) ? item.getOrder().getId() : null; } private Order obtainOrder(Long orderId) { return Objects.nonNull(orderId) ? orderRepository.findById(orderId).orElse(null) : null; } }
ูุฐู ุงูู
ุฎุทุทุงุช ุงูู
ูุชูุจุฉ ุฐุงุชูุง ููุง ุนููุจ ูุงุถุญุฉ:
- ูุง ู
ููุงุณ.
- ุนูุฏ ุฅุถุงูุฉ / ุฅุฒุงูุฉ ุญุชู ุงูุญูู ุงูุฃูุซุฑ ุฃูู
ูุฉ ุ ุณูููู ุนููู ุชุญุฑูุฑ ุงูู
ุฎุทุท.
ูุฐูู ุ ุงูุญู ุงูุตุญูุญ ูู ุงุณุชุฎุฏุงู
ู
ูุชุจุฉ ู
ุนูู. ุฃูุง ุฃุนุฑู modelmapper ู mapstruct. ู
ูุฐ ุฃู ุนู
ูุช ู
ุน ุนุงุฑุถ ุงููู
ุงุฐุฌ ุ ุณุฃุชุญุฏุซ ุนู ุฐูู ุ ููู ุฅุฐุง ููุช ุ ุฃููุง ุงููุงุฑุฆ ุงูุฎุงุต ุจู ุ ุนูู ุฏุฑุงูุฉ ุฌูุฏุฉ ุจู mapstruct ููู
ูู ุฃู ุชุฎุจุฑูุง ุจูู ุงูุชูุงุตูู ุงูุฏูููุฉ ูุชุทุจููู ุ ููุฑุฌู ูุชุงุจุฉ ู
ูุงู ุญููู ุ ูุณุฃููู ุฃูู ู
ู ููุชุจู ูู (ูุฐู ุงูู
ูุชุจุฉ ูู ุฃูุถูุง ู
ุซูุฑุฉ ููุงูุชู
ุงู
ุ ูููู ููุณ ููุงู ููุช ููุฏุฎูู ุฅูููุง ุญุชู ุงูุขู).
ูุฐูู modelmapper.
ุฃุฑูุฏ ุฃู ุฃููู ุนูู ุงูููุฑ ุฃูู ุฅุฐุง ูุงู ููุงู ุดูุก ุบูุฑ ูุงุถุญ ูู ุ ููู
ููู ุชูุฒูู ุงูู
ุดุฑูุน ุงูููุงุฆู ู
ู ุฎูุงู ุงุฎุชุจุงุฑ ุนู
ูู ุ ุฑุงุจุท ูู ููุงูุฉ ุงูู
ูุงูุฉ.
ุงูุฎุทูุฉ ุงูุฃููู ูู ุ ุจุงูุทุจุน ุ ุฅุถุงูุฉ ุชุจุนูุฉ. ุฃุณุชุฎุฏู
ู
ูุฒุฉ gradle ุ ููู ู
ู ุงูุณูู ุนููู ุฅุถุงูุฉ ุชุจุนูุฉ ุฅูู ู
ุดุฑูุน maven ุงูุฎุงุต ุจู.
compile group: 'org.modelmapper', name: 'modelmapper', version: '2.3.2'
ูุฐุง ูููู ูุชุดุบูู ุงูู
ุตู
ู
. ุจุนุฏ ุฐูู ุ ูุญู ุจุญุงุฌุฉ ุฅูู ุฅูุดุงุก ุตูุฏูู.
@Bean public ModelMapper modelMapper() { ModelMapper mapper = new ModelMapper(); mapper.getConfiguration() .setMatchingStrategy(MatchingStrategies.STRICT) .setFieldMatchingEnabled(true) .setSkipNullEnabled(true) .setFieldAccessLevel(PRIVATE); return mapper; }
ุนุงุฏุฉู ู
ุง ูููู ู
ุฌุฑุฏ ุฅุฑุฌุงุน ModelMapper ุฌุฏูุฏ ุ ูููู ูู ูููู ู
ู ุงูุถุฑูุฑู ุชูููู ุงูู
ุฎุทุท ูุชูุจูุฉ ุงุญุชูุงุฌุงุชูุง. ูู
ุช ุจุชุนููู ุงุณุชุฑุงุชูุฌูุฉ ู
ุทุงุจูุฉ ุตุงุฑู
ุฉ ุ ูุชู
ููู ุชุนููู ุงูุญูู ุ ูุชุฎุทู ุงูุญููู ุงูุฎุงููุฉ ุ ูุชุนููู ู
ุณุชูู ุฎุงุต ู
ู ุงููุตูู ุฅูู ุงูุญููู.
ุจุนุฏ ุฐูู ุ ูู
ุจุฅูุดุงุก ุจููุฉ ุงูููุงู ุงูุชุงููุฉ. ุณูููู ูุฏููุง ููููููุฑู ุ ูุงูุฐู ุณูููู ูู ุนุฏุฏ ู
ุนูู ู
ู ู
ุฑุคูุณูู ุ ููู ูุงุญุฏ ู
ููู
ุณูููู ูุฏูู ุนุฏุฏ ู
ุนูู ู
ู ุงููุนู.
ุงูููุงูุงุชุงูุฃุตู ู
ุฌุฑุฏุฉ:
@MappedSuperclass @Setter @EqualsAndHashCode @NoArgsConstructor @AllArgsConstructor public abstract class AbstractEntity implements Serializable { Long id; LocalDateTime created; LocalDateTime updated; @Id @GeneratedValue public Long getId() { return id; } @Column(name = "created", updatable = false) public LocalDateTime getCreated() { return created; } @Column(name = "updated", insertable = false) public LocalDateTime getUpdated() { return updated; } @PrePersist public void toCreate() { setCreated(LocalDateTime.now()); } @PreUpdate public void toUpdate() { setUpdated(LocalDateTime.now()); } }
ููููููุฑู:
@Entity @Table(name = "unicorns") @EqualsAndHashCode(callSuper = false) @Setter @AllArgsConstructor @NoArgsConstructor public class Unicorn extends AbstractEntity { private String name; private List<Droid> droids; private Color color; public Unicorn(String name, Color color) { this.name = name; this.color = color; } @Column(name = "name") public String getName() { return name; } @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "unicorn") public List<Droid> getDroids() { return droids; } @Column(name = "color") public Color getColor() { return color; } }
ุงูุฑูุจูุช:
@Setter @EqualsAndHashCode(callSuper = false) @Entity @Table(name = "droids") @AllArgsConstructor @NoArgsConstructor public class Droid extends AbstractEntity { private String name; private Unicorn unicorn; private List<Cupcake> cupcakes; private Boolean alive; public Droid(String name, Unicorn unicorn, Boolean alive) { this.name = name; this.unicorn = unicorn; this.alive = alive; } public Droid(String name, Boolean alive) { this.name = name; this.alive = alive; } @Column(name = "name") public String getName() { return name; } @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "unicorn_id") public Unicorn getUnicorn() { return unicorn; } @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "droid") public List<Cupcake> getCupcakes() { return cupcakes; } @Column(name = "alive") public Boolean getAlive() { return alive; } }
ูุจ ููู:
@Entity @Table(name = "cupcakes") @Setter @EqualsAndHashCode(callSuper = false) @AllArgsConstructor @NoArgsConstructor public class Cupcake extends AbstractEntity { private Filling filling; private Droid droid; @Column(name = "filling") public Filling getFilling() { return filling; } @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "droid_id") public Droid getDroid() { return droid; } public Cupcake(Filling filling) { this.filling = filling; } }
ุณูููู
ุจุชุญููู ูุฐู ุงูููุงูุงุช ุฅูู DTO. ููุงู ุทุฑููุชุงู ุนูู ุงูุฃูู ูุชุญููู ุงูุชุจุนูุงุช ู
ู ููุงู ุฅูู DTO. ูุงุญุฏ ูุนูู ุญูุธ ุงูู
ุนุฑู ููุท ุจุฏูุงู ู
ู ุงูููุงู ุ ูููู ุจุนุฏ ุฐูู ูู ููุงู ู
ู ุงูุชุจุนูุฉ ุ ุฅุฐุง ูุฒู
ุงูุฃู
ุฑ ุ ุณูููู
ุจุณุญุจ ุงูู
ุนุฑู ุจุงูุฅุถุงูุฉ ุฅูู ุฐูู. ุงูููุฌ ุงูุซุงูู ููุทูู ุนูู ุงูุญูุงุธ ุนูู DTO ุงูุชุงุจุนุฉ. ูุฐูู ุ ูู ุงูุทุฑููุฉ ุงูุฃููู ุ ุณูููู
ุจุชุญููู List droids ุฅูู List droids (ูููู
ููุท ุจุชุฎุฒูู ุงูู
ุนุฑูุงุช ูู ุงููุงุฆู
ุฉ ุงูุฌุฏูุฏุฉ) ุ ููู ุงูุทุฑููุฉ ุงูุซุงููุฉ ุ ุณูู ูููู
ุจุญูุธูุง ูู List droids.
DTOุงูุฃุตู ู
ุฌุฑุฏุฉ:
@Data public abstract class AbstractDto implements Serializable { private Long id; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss.SSS") LocalDateTime created; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss.SSS") LocalDateTime updated; }
UnicornDto:
@EqualsAndHashCode(callSuper = true) @Data @NoArgsConstructor @AllArgsConstructor public class UnicornDto extends AbstractDto { private String name; private List<DroidDto> droids; private String color; }
DroidDto:
@EqualsAndHashCode(callSuper = true) @Data @NoArgsConstructor @AllArgsConstructor public class DroidDto extends AbstractDto { private String name; private List<CupcakeDto> cupcakes; private UnicornDto unicorn; private Boolean alive; }
CupcakeDto:
@EqualsAndHashCode(callSuper = true) @Data @NoArgsConstructor @AllArgsConstructor public class CupcakeDto extends AbstractDto { private String filling; private DroidDto droid; }
ูุถุจุท ุงูู
ุตู
ู
ุญุณุจ ุงุญุชูุงุฌุงุชูุง ุ ุณูุญุชุงุฌ ุฅูู ุฅูุดุงุก ูุฆุฉ ู
ุฌู
ูุน ุฎุงุตุฉ ุจูุง ูุฅุนุงุฏุฉ ุชุญุฏูุฏ ู
ูุทู ู
ุฌู
ูุนุงุช ุงูุชุนููู. ููููุงู
ุจุฐูู ุ ูููู
ุจุฅูุดุงุก ูุฆุฉ ู
ููู UnicornMapper ุ ููููู
ุจุงูุชุนููู ุงูุชููุงุฆู ูู
ุฎุทุทูุง ููุงู ูุฅุนุงุฏุฉ ุชุญุฏูุฏ ุงูุฃุณุงููุจ ุงูุชู ูุญุชุงุฌูุง.
ูุจุฏู ุฃุจุณุท ุฅุตุฏุงุฑ ู
ู ูุฆุฉ ุงูู
ุฌู
ุน ู
ุซู ูุฐุง:
@Component public class UnicornMapper { @Autowired private ModelMapper mapper; @Override public Unicorn toEntity(UnicornDto dto) { return Objects.isNull(dto) ? null : mapper.map(dto, Unicorn.class); } @Override public UnicornDto toDto(Unicorn entity) { return Objects.isNull(entity) ? null : mapper.map(entity, UnicornDto.class); } }
ุงูุขู ุ ูููู ุฃู ูุถูู ู
ุตู
ู
ุงูุฎุฑุงุฆุท ุงูุฎุงุต ุจูุง ุฅูู ุฎุฏู
ุฉ ู
ุง ูุณุญุจูุง ุจุงุณุชุฎุฏุงู
ุฃุณุงููุจ toDto ู toEntity. ุณูููู
ู
ุฎุทุท ู
ุนูู ุจุชุญููู ุงูููุงูุงุช ุงูู
ูุฌูุฏุฉ ูู ุงููุงุฆู ุฅูู DTO ุ DTO - ุฅูู ููุงูุงุช.
@Service public class UnicornServiceImpl implements UnicornService { private final UnicornRepository repository; private final UnicornMapper mapper; @Autowired public UnicornServiceImpl(UnicornRepository repository, UnicornMapper mapper) { this.repository = repository; this.mapper = mapper; } @Override public UnicornDto save(UnicornDto dto) { return mapper.toDto(repository.save(mapper.toEntity(dto))); } @Override public UnicornDto get(Long id) { return mapper.toDto(repository.getOne(id)); } }
ูููู ุฅุฐุง ุญุงูููุง ุชุญููู ุดูุก ู
ุง ุจูุฐู ุงูุทุฑููุฉ ุ ุซู
ุงุชุตููุง ุ ุนูู ุณุจูู ุงูู
ุซุงู ุ ุจู "ุณูุณูุฉ" ุ ูุณูุญุตู ุนูู StackOverflowException ุ ูุฅูููู
ุงูุณุจุจ: ูุญุชูู UnicornDto ุนูู ูุงุฆู
ุฉ DroidDto ุ ุงูุชู ุชุญุชูู ุนูู UnicornDto ุ ูุงูุชู ุชุญุชูู ุนูู DroidDto ุ ูููุฐุง ุญุชู ุชูู ุงููุญุธุฉ ุญุชู ููุงุฏ ุฐุงูุฑุฉ ุงูู
ูุฏุณ. ูุฐูู ุ ุจุงููุณุจุฉ ุฅูู ุงูุชุจุนูุงุช ุงูู
ุนููุณุฉ ุ ุนุงุฏุฉู ู
ุง ุฃุณุชุฎุฏู
UnicornDto unicorn ุ ููู Long unicornId. ูุจูุฐู ุงูุทุฑููุฉ ุ ูุจูู ุนูู ุงุชุตุงู ู
ุน ููููููุฑู ุ ููููุง ููุทุน ุงูุงุนุชู
ุงุฏ ุงูุชุจุนู ุงูุฏูุฑู. ุฏุนููุง ุฅุตูุงุญ DTOs ูุฏููุง ุจุญูุซ ุจุฏูุงู ู
ู DTOs ุงูุนูุณู ุ ูุฅููุง ุชุฎุฒู ู
ุนุฑูุงุช ุชุจุนูุงุชูู
.
@EqualsAndHashCode(callSuper = true) @Data @NoArgsConstructor @AllArgsConstructor public class DroidDto extends AbstractDto { ...
ู ููุฐุง.
ูููู ุงูุขู ุ ุฅุฐุง ุงุชุตููุง ุจู DroidMapper ุ ูุณูุญุตู ุนูู unicornId == ูุงุฑุบุฉ. ูุฐุง ูุฃูู ูุง ูู
ูู ูู ModelMapper ุชุญุฏูุฏ ููุน Long ุจุงูุถุจุท. ูููุท ูุง ูุฒุนุฌู. ูุณูุชุนูู ุนูููุง ุถุจุท ุงูู
ุตู
ู
ูู ุงูุถุฑูุฑููู ูุชุนููู
ูู
ููููุฉ ุชุนููู ุงูููุงูุงุช ูู ุงูู
ุนุฑูุงุช.
ูุฐูุฑ ุฃูู ู
ุน ูู ุตูุฏูู ุจุนุฏ ุงูุชููุฆุฉ ุ ูู
ููู ุงูุนู
ู ูุฏูููุง.
@PostConstruct public void setupMapper() { mapper.createTypeMap(Droid.class, DroidDto.class) .addMappings(m -> m.skip(DroidDto::setUnicornId)).setPostConverter(toDtoConverter()); mapper.createTypeMap(DroidDto.class, Droid.class) .addMappings(m -> m.skip(Droid::setUnicorn)).setPostConverter(toEntityConverter()); }
ููPostConstruct ุณูุถุน ุงูููุงุนุฏ ุงูุชู ูุดูุฑ ูููุง ุฅูู ุงูุญููู ุงูุชู ูุง ูุฌุจ ุนูู ุงูู
ุฎุทุท ุชุนููููุง ุ ูุฃููุง ุณูุญุฏุฏ ุงูู
ูุทู ุงูุฎุงุต ุจูุง. ูู ุญุงูุชูุง ุ ูุฐุง ูู ุชุนุฑูู unicornId ูู DTO ุ ูุชุนุฑูู Unicorn ูู ุฌููุฑู (ูุธุฑูุง ูุฃู ุงูู
ุตู
ู
ูุง ูุนุฑู ุฃูุถูุง ู
ุง ูุฌุจ ูุนูู ู
ุน Long unicornId).
TypeMap - ูุฐู ูู ุงููุงุนุฏุฉ ุงูุชู ูุญุฏุฏ ูููุง ุฌู
ูุน ุงููุฑูู ุงูุฏูููุฉ ูู ุงูุชุนููู ุ ูุฃูุถูุง ุ ูู
ุจุชุนููู ุงูู
ุญูู. ููุฏ ุฃูุถุญูุง ุฃูู ููุชุญููู ู
ู Droid ุฅูู DroidDto ุ ูุชุฎุทู setUnicornId ุ ููู ุงูุชุญููู ุงูุนูุณู ุ ูู
ุฑ setUnicorn. ุณูููู
ุฌู
ูุนูุง ุจุงูุชุญููู ูู ู
ุญูู toDtoConverter () ูู UnicornDto ููู toEntityConverter () ูู Unicorn. ูุฌุจ ุฃู ูุตู ูุฐู ุงูู
ุญููุงุช ูู ุงูู
ููู ุงูุฎุงุต ุจูุง.
ุฃุจุณุท ู
ุง ุจุนุฏ ุงูู
ุญูู ูุดุจู ูุฐุง:
Converter<UnicornDto, Unicorn> toEntityConverter() { return MappingContext::getDestination; }
ูุญู ุจุญุงุฌุฉ ุฅูู ุชูุณูุน ูุธุงุฆููุง:
public Converter<UnicornDto, Unicorn> toEntityConverter() { return context -> { UnicornDto source = context.getSource(); Unicorn destination = context.getDestination(); mapSpecificFields(source, destination); return context.getDestination(); }; }
ููุนู ููุณ ุงูุดูุก ู
ุน ุงูู
ุญูู ุงูุนูุณู:
public Converter<Unicorn, UnicornDto> toDtoConverter() { return context -> { Unicorn source = context.getSource(); UnicornDto destination = context.getDestination(); mapSpecificFields(source, destination); return context.getDestination(); }; }
ูู ุงููุงูุน ุ ูููู
ุจุจุณุงุทุฉ ุจุฅุฏุฎุงู ุทุฑููุฉ ุฅุถุงููุฉ ูู ูู ู
ุญูู ูุงุญู ุ ููุชุจ ููู ู
ูุทููุง ุงูุฎุงุต ููุญููู ุงูู
ูููุฏุฉ.
public void mapSpecificFields(Droid source, DroidDto destination) { destination.setUnicornId(Objects.isNull(source) || Objects.isNull(source.getId()) ? null : source.getUnicorn().getId()); } void mapSpecificFields(DroidDto source, Droid destination) { destination.setUnicorn(unicornRepository.findById(source.getUnicornId()).orElse(null)); }
ุนูุฏ ุงูุชุนููู ูู DTO ุ ูููู
ุจุชุนููู ู
ุนุฑู ุงูููุงู. ุนูุฏ ุงูุชุนููู ูู DTO ุ ูุญุตู ุนูู ุงูููุงู ู
ู ุงูู
ุณุชูุฏุน ุจู
ุนุฑู.
ููุฐุง ูู ุดูุก.
ููุฏ ุฃุธูุฑุช ุงูุญุฏ ุงูุฃุฏูู ุงูุถุฑูุฑู ูุจุฏุก ุงูุนู
ู ู
ุน modelmapper ููู
ุชูู
ุจุฅุนุงุฏุฉ ุชุดููู ุงูุฑู
ุฒ ุจุดูู ุฎุงุต. ุฅุฐุง ููุช ุ ุฃููุง ุงููุงุฑุฆ ุ ูุฏูู ู
ุง ุชุถููู ุฅูู ู
ูุงูุชู ุ ูุณุฃููู ุณุนูุฏูุง ูุณู
ุงุน ุงูููุฏ ุงูุจูุงุก.
ูู
ูู ุงูุงุทูุงุน ุนูู ุงูู
ุดุฑูุน ููุง:
ู
ุดุฑูุน ุนูู ุฌูุซุจ.ู
ู ุงูู
ุญุชู
ู ุฃู ูููู ุนุดุงู ุงูููุฏ ุงููุธูู ูุฏ ุฑุฃูุง ุจุงููุนู ุงููุฑุตุฉ ูุฏูุน ุงูุนุฏูุฏ ู
ู ู
ูููุงุช ุงูููุฏ ุฅูู ุงูุชุฌุฑูุฏ. ุฅุฐุง ููุช ูุงุญุฏุง ู
ููู
ุ ุฃูุชุฑุญ ุชุญุช ุงููุท.
ุฑูุน ู
ุณุชูู ุงูุชุฌุฑูุฏุจุงุฏุฆ ุฐู ุจุฏุก ุ ูููู
ุจุชุนุฑูู ูุงุฌูุฉ ููุทุฑู ุงูุฃุณุงุณูุฉ ููุฆุฉ ุงูุงูุชูุงู.
public interface Mapper<E extends AbstractEntity, D extends AbstractDto> { E toEntity(D dto); D toDto(E entity); }
ูุฑุซ ู
ูู ุทุจูุฉ ู
ุฌุฑุฏุฉ.
public abstract class AbstractMapper<E extends AbstractEntity, D extends AbstractDto> implements Mapper<E, D> { @Autowired ModelMapper mapper; private Class<E> entityClass; private Class<D> dtoClass; AbstractMapper(Class<E> entityClass, Class<D> dtoClass) { this.entityClass = entityClass; this.dtoClass = dtoClass; } @Override public E toEntity(D dto) { return Objects.isNull(dto) ? null : mapper.map(dto, entityClass); } @Override public D toDto(E entity) { return Objects.isNull(entity) ? null : mapper.map(entity, dtoClass); } Converter<E, D> toDtoConverter() { return context -> { E source = context.getSource(); D destination = context.getDestination(); mapSpecificFields(source, destination); return context.getDestination(); }; } Converter<D, E> toEntityConverter() { return context -> { D source = context.getSource(); E destination = context.getDestination(); mapSpecificFields(source, destination); return context.getDestination(); }; } void mapSpecificFields(E source, D destination) { } void mapSpecificFields(D source, E destination) { } }
ูู
ูู ุฅุฑุณุงู ุงูู
ุญููุงุช ุงููุงุญูุฉ ูุทุฑู ู
ูุก ุงูุญููู ุงูู
ุญุฏุฏุฉ ุจุฃู
ุงู ุฅูู ููุงู. ุฃูุถูุง ุ ูู
ุจุฅูุดุงุก ูุงุฆููู ู
ู ุงูููุน Class ูู
ูุดุฆ ูุชููุฆุฉูู
ุง:
private Class<E> entityClass; private Class<D> dtoClass; AbstractMapper(Class<E> entityClass, Class<D> dtoClass) { this.entityClass = entityClass; this.dtoClass = dtoClass; }
ุงูุขู ูุชู
ุชูููู ู
ูุฏุงุฑ ุงูุชุนููู
ุงุช ุงูุจุฑู
ุฌูุฉ ูู DroidMapper ุฅูู ู
ุง ููู:
@Component public class DroidMapper extends AbstractMapper<Droid, DroidDto> { private final ModelMapper mapper; private final UnicornRepository unicornRepository; @Autowired public DroidMapper(ModelMapper mapper, UnicornRepository unicornRepository) { super(Droid.class, DroidDto.class); this.mapper = mapper; this.unicornRepository = unicornRepository; } @PostConstruct public void setupMapper() { mapper.createTypeMap(Droid.class, DroidDto.class) .addMappings(m -> m.skip(DroidDto::setUnicornId)).setPostConverter(toDtoConverter()); mapper.createTypeMap(DroidDto.class, Droid.class) .addMappings(m -> m.skip(Droid::setUnicorn)).setPostConverter(toEntityConverter()); } @Override public void mapSpecificFields(Droid source, DroidDto destination) { destination.setUnicornId(getId(source)); } private Long getId(Droid source) { return Objects.isNull(source) || Objects.isNull(source.getId()) ? null : source.getUnicorn().getId(); } @Override void mapSpecificFields(DroidDto source, Droid destination) { destination.setUnicorn(unicornRepository.findById(source.getUnicornId()).orElse(null)); } }
ู
ุฎุทุท ู
ุนูู ุจุฏูู ุญููู ู
ุญุฏุฏุฉ ูุจุฏู ุนู
ูู
ูุง ุจุณูุทูุง:
@Component public class UnicornMapper extends AbstractMapper<Unicorn, UnicornDto> { @Autowired public UnicornMapper() { super(Unicorn.class, UnicornDto.class); } }