首页
Preview

📋 Java对象映射框架:全面指南!

在数据驱动的应用程序中工作时,Java对象映射是一项必要的任务,因为它允许我们在不同的数据结构之间进行转换,简化数据访问和操作。为了帮助Java开发人员处理映射挑战,多个Java映射框架已经在多年内被开发出来。每个框架都有其自身的优点和缺点,使得开发人员难以选择适合他们使用情况的正确框架。

在本文中,我们将深入探讨四个流行的Java映射框架:MapStruct、ModelMapper和JMapper。我们将探讨每个框架的使用,以及提供代码示例,帮助你了解如何在实践中使用它们。

通过本文,你将对这些Java映射框架有扎实的了解,并能够选择最适合你项目特定需求的框架。

🚩 起点

在Java应用程序中,使用不同的数据结构来处理不同的目的是很常见的。 例如,你可能有一个对象模型,代表你的域中的实体,例如客户、订单或产品。同时,你可能需要与不同的数据结构进行交互,例如数据传输对象(DTO),用于在应用程序的不同层之间或外部系统之间传输数据。

需要在不同的数据结构之间进行转换,例如域对象和DTO,这导致了Java映射框架的开发。这些框架自动化了将一个对象映射到另一个对象的过程,节省了开发人员的时间并降低了错误的可能性。

**DTO或数据传输对象是一个Java对象,用于封装数据并在不同的层或系统之间传输数据。**DTO通常包含域对象的一部分字段,并且它们被设计为轻量级和高效,以便在网络上或应用程序的不同部分之间传输。通过使用DTO,开发人员可以将域模型的关注点与数据传输的关注点分离,使他们的代码更模块化和更易于维护。

对于我们的案例,我们将定义域实体User:

public class User{
    private Long id;
    private String name;
    private String surname;
    private String email;
    private LocalDate creationDate;
    private List<String> addresses;
    private String role;

    // Getters y setters
}

以及相应的DTO:

public class UserDto {
    private String name;
    private String surname;
    private String email;
    private List<String> addresses;

    // Getters y setters
}

这些将是我们将使用和测试的类和不同映射框架。

📕 MapStruct

要开始使用MapStruct,我们需要将maven依赖项添加到我们项目的pom.xml中:

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.5.3.Final</version> 
</dependency>

让我们还在maven-compiler-plugin插件的配置部分中添加annotationProcessorPaths部分。

在构建过程中,使用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.5.3.Final</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

一旦我们完成了所有这些,我们就可以定义我们的映射器。要做到这一点,我们只需要定义一个接口,我们将其称为UserMapper,并使用@Mapper注释标记它。

(_🚩_如果我们想要将其注入为Bean到任何其他Spring组件中,需要添加带有值componentModel =的参数:&#34;spring”):

@Mapper(componentModel = "spring")
public interface UserMapper {

  UserDto toDto(User user);

  User toEntity(UserDto dto);

}

在这种情况下,由于DTO和实体的字段名称匹配,因此无需向我们的映射器添加任何其他内容。

但是如果一些字段不匹配 ,例如在DTO中名称以西班牙语“nombre”定义,则我们需要在映射方法上方添加注释@Mapping ,指示源字段和目标字段的名称,例如:

  @Mapping(target = "nombre", source = "name")
  UserDto toDto(User user);

现在我们已经准备好使用我们的映射器了,例如在我们的服务中。在我们的服务中,我们将使用 @Autowired 注释注入它,然后调用我们在接口中定义的相应方法,例如:

@Service
public class UserService {

  @Autowired
  private UserRepository userRepository;

  @Autowired
  private UserMapper userMapper;

  @Transactional(readOnly = true)
  public UserDto getUser(Long id) {
    return userMapper.toDto(userRepository.findById(id).orElseThrow(() -> new EntityNotFoundException("User not found")));
  }

}

📘 ModelMapper

要开始使用ModelMapper,我们需要将maven依赖项添加到我们项目的pom.xml中:

<dependency>
    <groupId>org.modelmapper</groupId>
    <artifactId>modelmapper</artifactId>
    <version>2.4.5</version>
</dependency>

与前一个不同,ModelMapper不需要更多的配置方面,只需在Maven项目的_pom.xml_文件中定义依赖项,我们就拥有了使用这个工具所需的一切。

在我们的情况下,由于我们想将其注入为Bean到我们的服务中,因此我们将不得不像这样在配置类中定义它:

@Configuration
public class Mapper {

  @Bean
  public ModelMapper modelMapper() {
    return new ModelMapper();
  }
  
}

完成后,我们可以使用**@Autowired注释注入它。要使用它,我们将使用ModelMapper**提供的map方法,作为第一个参数传递要转换的对象,作为第二个参数传递要将对象转换为的类。因此,这将是其使用示例:

@Service
public class UserService {

  @Autowired
  private UserRepository userRepository;

  @Autowired
  private ModelMapper mapper;

  @Transactional(readOnly = true)
  public UserDto getUser(Long id) {
    return mapper.map(userRepository.findById(id).orElseThrow(() -> new EntityNotFoundException("User doesnt exist")), UserDto.class);
  }

}

例如,如果我们想要自定义字段映射,例如上面提到的“name”字段的示例,则需要获取负责映射两个对象之间的typeMap,并将此规则添加到我们定义的映射器中:

mapper.getTypeMap(User.class,UserDto.class).addMapping(User::getName,UserDto::setNombre);

📗 JMapper

要开始使用JMapper,我们需要将maven依赖项添加到我们项目的_pom.xml_中:

<dependency>
    <groupId>com.googlecode.jmapper-framework</groupId>
    <artifactId>jmapper-core</artifactId>
    <version>1.6.0.1</version>
</dependency>

我们将为对象映射定义一个Bean,与前一个案例相同,因此我们可以将其注入到我们的服务中:

@Configuration
public class Mapper {

  @Bean
  public JMapper<UserDto,User> userMapper() {
    return new JMapper<>(UserDto.class, User.class);
  }

}

为了能够执行映射,JMapper需要添加一个额外的方面,即源和目标对象的字段对应关系。对于此,JMapper有3种不同的方法:使用JMapperAPI,使用注释或使用XML配置。对于我们的示例,我们将使用注释,但你可以在以下链接中找到更多信息:(https://www.baeldung.com/jmapper)。只需要在 DTO 类的每个属性上添加 @JMap 注释即可完成操作:

@Data
public class UserDto implements Serializable {

  @JMap
  private String name;
  @JMap
  private String surname;
  @JMap
  private String email;
  
  @JMap
  private List<String> addresses;

}

一旦我们拥有了所需的一切,我们只需要将 Bean 注入到服务中,并调用 JMapper 提供的相应方法,即可从 User 实体中获取 UserDto 对象:

@Service
public class UserService {

  @Autowired
  private UserRepository userRepository;

  @Autowired
  private JMapper<UserDto, User> userMapper;

  @Transactional(readOnly = true)
  public UserDto getUser(Long id) {
    return userMapper.getDestination(userRepository.findById(id).orElseThrow(() -> new EntityNotFoundException("User doesnt exist")));
  }

}

要创建自定义属性映射,只需在目标类的 @JMap 注释中指定源属性的名称即可。例如,如果 UserDto 有一个与实体 Username 字段对应的 nombre 字段:

@JMap("name")
 private String nombre;

📙 在结束文章之前,我想特别提到其他存在的框架,比如:

🚨 此外,我想向你展示以下链接:https://www.baeldung.com/java-performance-mapping-frameworks,其中对不同情况下的性能和效率进行了深入分析。

🏁结论

总之,在使用 Java 映射框架时,需要考虑易用性、性能和自定义选项等因素。选择正确的框架取决于项目的具体要求和偏好。通过利用这些框架,你可以简化对象映射并增强 Java 应用程序的效率。

每个框架的使用取决于项目的需求或每个用户发现的易用性。在本文中,我试图讨论主要框架以及如何在我们的项目中实现它们。

译自:https://medium.com/@miguelangelperezdiaz444/comparing-java-mapping-frameworks-a-performance-analysis-f36d68c729e3

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
阿波
The minute I see you, I want your clothes gone!

评论(0)

添加评论