繁体   English   中英

如何将 DTO 映射到现有的 JPA 实体?

[英]How to map a DTO to an existing JPA entity?

我正在尝试将 Java DTO 对象映射到现有的 JPA 实体对象,而无需执行以下操作:

public MyEntity mapToMyEntity(SomeDTO dto, MyEntity entity) {
    entity.setField1(dto.getField1());
    entity.setField2(dto.getField2());
    ...
    entity.setField20(dto.getField20());

    return entity;
}

到目前为止,我一直在使用ModelMapperMyEntity entity = modelMapper.map(dto, SomeDTO.class); ,但我想做的是映射到现有的实体对象,而不是从 DTO 创建新的实体对象。 我浏览了 ModelMapper 手册,找不到如何在不创建新对象的情况下进行映射。 我是否坚持为我可能拥有的每个实体对象手动添加每个成员变量?

您可以使用推土机映射器或 gson。

DozerMapper 前:

Mapper mapper = DozerBeanMapperBuilder.createDefault();
DestinationObject destObject = mapper.map(sourceObject,DestinationClassName.class);

您可以查看github 页面以获取更多信息

您可以定义下一个类:

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;
    }
}

并根据您的需要使用它:

MyEntity entity = ObjectMapperUtils.map(dto, existingEntity);

目前ModelMapper也支持映射到现有对象。

可以执行以下操作(对于伪 Spring 示例):

MyEntity mye = repository.findById(id);
ModelMapper mm = new ModelMapper();    
mm.map(myDTO, mye);
repository.save(mye):

我使用的是 2.3.1 版,但早期版本也可能支持此功能

我们可以在这里使用 Map Struct。 有关如何使用它的参考链接: https : //www.baeldung.com/mapstruct

翻译自葡萄牙语

https://pt.stackoverflow.com/questions/166438/dto-assembler-como-utiliza-lo-realmente

使用模式汇编器:您可以通过汇编器模式将实体转换为 DTO,但这是错误的(我认为),它打破了作为传输对象标准的 DTO 的意义。 看到它可以由几个实体组成。 正确的做法是使用服务类中对象实例的 set 方法,将 DTO 组合为实体,这仅仅是因为您正确地使用了标准。

但它有一种方法,即使它是错误的,它也能工作,但实体 x DTO 之间只有 1 x 1 关联,使用 Guava 函数。

例如:将 Translate 转换为对象和列表

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;
        }    
    }

模式汇编器:

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);
    }
}

使用这些模式的服务是什么......

/**
 * 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());
}

现在让我们执行将一个或一组 DTO 转换为对象的逆过程,但请记住,关联是 1x1。 为此,只需在函数的实现中反转对象,例如:

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);
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM