【问题标题】:Alternative options for step-by-step object update in Java [duplicate]Java中逐步对象更新的替代选项[重复]
【发布时间】:2019-08-06 20:18:10
【问题描述】:

我会说这只是一个好奇而不是一个问题,但重点是下一个:

我使用 Spring Framework 构建了一个简单的 REST API。不需要关注所有实现的类和接口,所以下面只提到概念和逻辑模型。

1. 长话短说,假设我有一个基本的用户实体(自动生成的 ID、姓名、电子邮件和密码)和角色实体(自动生成的 ID 及其名称)。对于这两者,还实现了包含所有 CRUD 操作的存储库、服务和控制器。

用于PUT方法,用户更新功能如下:

@Transactional
public void updateUser(Integer id, User user, Integer roleId) {
    Role role = roleRepository.findById(roleId).get();
    User userToUpdate = userRepository.findById(id).get();

    userToUpdate.setName(user.getName());
    userToUpdate.setEmail(user.getEmail());
    userToUpdate.setPassword(user.getPassword());
    userToUpdate.setRole(role);
    userToUpdate.setDevices(user.getDevices());

    userRepository.save(userToUpdate);
}

虽然这个代码片段工作正常,但由于它的逐步设置器的使用,它让我感到恼火和沮丧。问题是 - 是否有任何其他选项可以简化给定的摘录(例如,Stream API 的某些功能等)?

2. 问题的第二部分与之前的摘录非常相关。这是另一段代码,负责 GET 方法返回具有特定角色的所有用户。但是对于响应实体,所有的对象都被包装到 DTO 原型中,随后的程序实现:

@GetMapping(value = "/roles/{roleId}/users")
public ResponseEntity<Set<UserDTO>> getUsersByRoleId(@PathVariable Integer roleId) {
    Set<User> users = userService.getUsersByRoleId(roleId);

    Link link = linkTo(methodOn(UserController.class).getAllUsers()).withSelfRel();

    Set<UserDTO> userSet = new HashSet<>();
    for (User entity : users) {
        Link selfLink = new Link(link.getHref() + "/" + entity.getId()).withSelfRel();
        UserDTO dto = new UserDTO(entity, selfLink);
        userSet.add(dto);
    }

    return new ResponseEntity<>(userSet, HttpStatus.OK);
}

同样,是否存在任何不同的解决方案来替代烦人的“for 循环”?

编辑:我对某些库/框架不感兴趣,但对仅使用纯 Java 的可能的简化/替代方案感兴趣

【问题讨论】:

  • 由于userSet 是一个集合,您可以使用while(userSet.iterator().hasNext())... 代替for 循环。 ;)
  • 基本上,您要求在 Java 中进行对象到对象的映射。
  • 亲爱的@Luiggi Mendoza,不幸的是,我不是在询问一些工具或框架来完成所提到的工作,而是 - 使用纯 Java 进行一些替代或简化。我会编辑我的帖子以避免将来可能出现的误解。
  • Java 的替代方案非常相似:1)您手动编写代码,2)您开始编写一些类和方法来使用反射来完成这项工作,3)您使用已经工作的框架如 dup Q/A 中所述

标签: java spring rest object java-stream


【解决方案1】:

MapStruct 是一个流行的库,可以自动创建这种映射代码。

【讨论】:

    【解决方案2】:

    对于简单地将一个对象转换为另一个对象(比如说User -&gt; DTO),您可以轻松地使用ModelMapper 或任何类似的工具 - Java 没有为您提供这种要求的任何本机解决方案

    @GetMapping(value = "/roles/{roleId}/users")
    public ResponseEntity<Set<UserDTO>> getUsersByRoleId(@PathVariable Integer roleId) {
        ModelMapper modelMapper = new ModelMapper();
        Set<UserDTO> users = userService
            .getUsersByRoleId(roleId)
            .stream()
            .map(user -> modelMapper.map(user , UserDTO.class))
            .peek(dto -> dto.setSelfLink(generateSelfLink(dto))
            .collect(toSet());
    
        return new ResponseEntity<>(userSet, HttpStatus.OK);
    }
    

    但是合并现有实例与传入的实例肯定是一个问题,对于这种要求,我建议您在 User 类中实现自己的 merge 方法

    //User class
    public User merge(User user) {
        setName(user.getName());
        setEmail(user.getEmail());
        setPassword(user.getPassword());
        setRole(role);
        setDevices(user.getDevices());
        return this;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-08
      • 1970-01-01
      • 2019-02-10
      • 2016-07-26
      • 2011-06-12
      • 2014-11-15
      • 2015-01-30
      相关资源
      最近更新 更多