有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring Boot:如何高效地更新对象?

大家好,我是春天世界的新手。实际上,我想知道我们如何使用转换器来更新对象,而不是使用set和get逐个更新每个元素。现在,在我的控制器中,我:

    @PostMapping("/edit/{userId}")
    public Customer updateCustomer(@RequestBody Customer newCustomer, @PathVariable final String userId)
    {
        return customerService.update(userId, newCustomer);
    }

这就是我更新客户对象的方式:

    @Override
    public Customer update(String id, Customer newCustomer) {
        Customer customer = customerRepository.findById(id).get();

        customer.setFirstName(newCustomer.getFirstName());
        customer.setLastName(newCustomer.getLastName());
        customer.setEmail(newCustomer.getEmail());

        return customerRepository.save(customer);
    }

我想使用一个转换器,而不是使用每次设置和获取时间


共 (1) 个答案

  1. # 1 楼答案

    在更新实体id时,将其作为路径变量传递的方法并不正确。想一想:你有一个@RequestBody,为什么不把这个id也包含在这个身体里呢?为什么要为其指定路径变量

    现在,如果你有一个完整的Customer和它的主体id,你不需要对你的存储库进行任何调用,因为hibernate已经基于它的id和一个简单的

    public Customer update(Customer newCustomer) {
          return customerRepository.save(newCustomer);
    }
    

    应该有用

    Q:什么是持续状态

    A:持久化实体已与数据库表行关联,并由当前运行的持久化上下文管理。(customerRepository.findById()只是询问数据库是否存在具有指定id的实体,并将其添加到持久状态。如果有@Id注释的字段并已填充,则Hibernate将管理所有此过程,换句话说:

       Customer customer = new Customer();
       customer.setId(1); 
    

    几乎是同一件事吗

       Customer customer = customerRepository.findById(1).get();
    

    )

    提示:无论如何,你不应该(如果你不知道)在控制器层有一个模型。为什么?假设你的Customer模型可以有多个权限。一种可能的结构如下所示:

    @Entity
    public class Customer{
       //private fields here;
    
       @OneToMany(mappedBy="customer", other configs here )
       private List<Permission> permissions;
    }
    

    @Entity
    public class Permission{
        @Id
        private Long id;
    
        private String name;
    
        private String creationDate;
    
        @ManyToOne( configs here )
        private Customer customer;
    }
    

    您可以看到CustomerPermission实体之间有一个交叉引用,这最终会导致堆栈溢出异常(如果您不理解这一点,可以考虑一个递归函数,它没有停止的条件,并且被反复调用=>;堆栈溢出。这里也发生了同样的情况)

    你能做什么?创建一个所谓的DTO类,希望客户端接收该类,而不是模型。如何创建此DTO?想想用户需要知道什么

    1)来自Permission的“creationDate”是否是用户必需的字段?不是真的

    2)来自Permission的“id”对用户来说是必需的字段吗?在某些情况下是的,在另一些情况下不是

    一个可能的CustomerDTO可以如下所示:

    public class CustomerDTO
    {
       private String firstName;
       private String lastName;
       private List<String> permissions;
    }
    

    您可以注意到,我使用了List<String>而不是List<Permission>来表示客户的权限,这实际上是权限的名称

    public CustomerDTO convertModelToDto(Customer customer)
    {
        //hard way
        CustomerDTO customerDTO = new CustomerDTO();
        customerDTO.setFirstName(customer.getFirstName());
        customerDTO.setLastName(customer.getLastName());
        customerDTO.setPermissions(
           customer.getPermissions()
                   .stream()
                   .map(permission -> permission.getName())
                   .collect(Collectors.toList());
        );
    
        // easy-way => using a ModelMapper
        customerDTO = modelMapper.map(customer,CustomerDTO.class);
    
        return customerDTO;
    }