J'essaie de mapper un objet Java DTO sur un objet entité JPA existant sans avoir à effectuer les opérations suivantes:
public MyEntity mapToMyEntity(SomeDTO dto, MyEntity entity) {
entity.setField1(dto.getField1());
entity.setField2(dto.getField2());
...
entity.setField20(dto.getField20());
return entity;
}
Jusqu'à présent, j'utilisais ModelMapper like so: MyEntity entity = modelMapper.map(dto, SomeDTO.class);
, mais j'essaie plutôt de mapper un objet d'entité existant au lieu de créer un objet d'entité new à partir de un DTO. J'ai parcouru le manuel de ModelMapper et je n'ai pas trouvé comment mapper sans créer un nouvel objet. Suis-je obligé d'ajouter chaque variable membre manuellement pour chaque objet d'entité que je pourrais avoir?
Vous pouvez utiliser Dozer Mapper ou gson.
DozerMapper ex:
Mapper mapper = DozerBeanMapperBuilder.createDefault();
DestinationObject destObject = mapper.map(sourceObject,DestinationClassName.class);
Vous pouvez vérifier page github pour plus d'informations
ModelMapper
prend actuellement en charge le mappage également vers un objet existant.
Il est possible de faire ce qui suit (pour un pseudo exemple Spring):
MyEntity mye = repository.finById(id);
ModelMapper mm = new ModelMapper();
mm.map(myDTO, mye);
repository.save(mye):
J'utilise la version 2.3.1, mais des versions antérieures pourraient prendre en charge cette fonctionnalité également
Vous pouvez définir la classe suivante:
public class ObjectMapperUtils {
private static ModelMapper modelMapper = new ModelMapper();
/**
* Model mapper property setting are specified in the following block.
* Default property matching strategy is set to Strict see {@link MatchingStrategies}
* Custom mappings are added using {@link ModelMapper#addMappings(PropertyMap)}
*/
static {
modelMapper = new ModelMapper();
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
}
/**
* Hide from public usage.
*/
private ObjectMapperUtils() {
}
/**
* <p>Note: outClass object must have default constructor with no arguments</p>
*
* @param <D> type of result object.
* @param <T> type of source object to map from.
* @param entity entity that needs to be mapped.
* @param outClass class of result object.
* @return new object of <code>outClass</code> type.
*/
public static <D, T> D map(final T entity, Class<D> outClass) {
return modelMapper.map(entity, outClass);
}
/**
* <p>Note: outClass object must have default constructor with no arguments</p>
*
* @param entityList list of entities that needs to be mapped
* @param outCLass class of result list element
* @param <D> type of objects in result list
* @param <T> type of entity in <code>entityList</code>
* @return list of mapped object with <code><D></code> type.
*/
public static <D, T> List<D> mapAll(final Collection<T> entityList, Class<D> outCLass) {
return entityList.stream()
.map(entity -> map(entity, outCLass))
.collect(Collectors.toList());
}
/**
* Maps {@code source} to {@code destination}.
*
* @param source object to map from
* @param destination object to map to
*/
public static <S, D> D map(final S source, D destination) {
modelMapper.map(source, destination);
return destination;
}
}
Et utilisez-le pour vos besoins:
MyEntity entity = ObjectMapperUtils.map(dto, existingEntity);
Traduit du Portugais
https://pt.stackoverflow.com/questions/166438/dto-assembler-como-utiliza-lo-realmente
Utilisez Pattern Assembler: Vous pouvez convertir Entity en DTO à travers le motif assembleur, mais il est faux (je pense), cela brise le sens du DTO, qui est un standard pour le transfert d'objets. Voir qu'il peut être composé de plusieurs entités. La bonne chose à faire est d’utiliser des méthodes de définition des instances des objets dans les classes de services, en prenant les DTO et en les assemblant en tant qu’entités, c’est simplement parce que vous travaillez correctement avec le standard.
Mais il y a un moyen que même s’il se trompe, cela fonctionnerait, mais seulement une association 1 x 1 entre entité x DTO, utilise la fonction Guava.
Ex: convertir Traduire pour transformer en objets et en listes avec
import Java.util.ArrayList;
import Java.util.List;
import com.google.common.base.Function;
/**
* Classe de transformação para popular os dados em DTOs, seguindo o pattern
* Transfer Object Assembler.
*/
public class Transformer {
/**
* Executa a transformação de um objeto para um DTO.
*
* @param from
* @param function
* @return <F, T> T
*/
public static <F, T> T transform(F from, Function<? super F, ? extends T> function) {
return (from == null) ? null : function.apply(from);
}
/**
* Executa a transformação de uma lista de objetos para uma lista de DTOs.
*
* @param fromList
* @param function
* @return <F, T> List<T>
*/
public static <F, T> List<T> transform(List<F> source, Function<? super F, ? extends T> function) {
List<T> out = new ArrayList<>(source.size());
for (F from : source) {
out.add(function.apply(from));
}
return out;
}
}
Assembleur de patrons:
import Java.util.List;
import br.com.myapp.model.dto.AuthUserDTO;
import br.com.myapp.model.entity.AuthUser;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
/**
* Classe que transforma entidade USUARIOS em DTO.
*
* @author Dilnei Cunha
*/
public class AuthUserDTOAssembler implements Function<AuthUser, AuthUserDTO>{
/**
* Método responsável por fazer a conversão da entidade USUARIOS em um AuthUserDTO.
*/
@Override
public AuthUserDTO apply(AuthUser e) {
AuthGroupDTO groupDTO = Transformer.transform(e.getAuthGroup(), new AuthGroupDTOAssembler());
return new AuthUserDTO(e.getId(),
e.getName(),
e.getPassword(),
e.getEmail(),
e.getCreationDate(),
e.getLastModificationdate(),
e.getLastAccessDate(),
e.getAtivo(),
e.getUserName(),
e.getRamal(),
groupDTO);
}
}
Quel serait le service qui utiliserait ces modèles ...
/**
* Método responsável por buscar um AuthUserDTO pelo ID do usuário.
*/
@Override
public AuthUserDTO findById(Long id) {
return Transformer.transform(authUserRepository.findUserById(id), new AuthUserDTOAssembler());
}
Faisons maintenant le processus inverse consistant à transformer un ou une liste de DTO en objets, mais gardez à l’esprit que l’association était 1x1. Pour ce faire, il suffit d'inverser les objets dans l'implémentation de la fonction, par exemple:
import Java.util.List;
import br.com.myapp.model.dto.AuthUserDTO;
import br.com.myapp.model.entity.AuthUser;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
/**
* @author Dilnei Cunha
*/
public class AuthUserAssembler implements Function<AuthUserDTO, AuthUser>{
@Override
public AuthUser apply(AuthUserDTO e) {
AuthGroup group = Transformer.transform(e.getAuthGroupDTO(), new AuthGroupAssembler());
return new AuthUser(e.getId(),
e.getName(),
e.getPassword(),
e.getEmail(),
e.getCreationDate(),
e.getLastModificationdate(),
e.getLastAccessDate(),
e.getAtivo(),
e.getUserName(),
e.getRamal(),
group);
}
}