【问题标题】:How to map a DTO to an existing JPA entity?如何将 DTO 映射到现有的 JPA 实体?
【发布时间】:2017-10-03 01:48:10
【问题描述】:

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

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

    return entity;
}

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

【问题讨论】:

    标签: java spring hibernate modelmapper


    【解决方案1】:

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

    DozerMapper 前:

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

    您可以查看github page了解更多信息

    【讨论】:

    • 虽然这是一个很好的建议,但我认为这与 OP 实际所做的没有什么不同。 OP 正在询问如何从 DTO 映射到 现有实体实例,而不是新实例。我猜是mapper.map(dto, entityObj) 之类的东西。
    【解决方案2】:

    你可以定义下一个类:

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

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

        【解决方案4】:

        我们可以在这里使用 Map Struct。 使用方法参考链接:https://www.baeldung.com/mapstruct

        【讨论】:

          【解决方案5】:

          翻译自葡萄牙语

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-09-13
            • 1970-01-01
            • 2022-07-14
            • 2021-12-31
            • 1970-01-01
            相关资源
            最近更新 更多