Spring Boot JPA Crudrepository选择性更新 - 仅一些属性



在使用Spring Boot JPA使用Hibernate时,我注意到,在试图在扩展Spring的Crudrepository接口的存储库中实现更新方法时,必须传递要更新的整个实体对象在这样的更新方法中。只是直观地看上去很浪费,我想知道什么是一种清洁的方法来获取春季数据/JPA,以假设只有需要更新的值传递并将未通过的那些值不受欢迎。

这是现在的服务方法,

   public void updateCustomer(Long id, Customer customer) throws Exception {
        customerRepository.save(customer);
    }

在JPA中,您通过实体,框架算出了您已更改的属性。如果您还不知道这一点,我建议您花更多的时间阅读有关JPA的基础知识。从表面上看,JPA看起来很容易且平易近人,但是如果您不了解其构建的原理,您最终将花费大量时间调试和谷歌搜索以破译错误消息。

当实体被管理时,JPA将在对象加载时将其副本进行副本,然后将其与传递给save/persist的版本进行比较,并确定应更新哪些列。这是一个易于使用的开发人员模型,您(通常)不必考虑对实体的更改。

您可能会认为,正如Rob所建议的那样,加载一个实体更改单个属性是浪费的,但并非总是如此。Eclipselink和Hibernate均使用共享(第二级)缓存默认情况下,因此,如果已经加载了实体,则可以从内存而不是DB加载它,并且一旦您修改了Entity,JPA将在内存中比较两个对象,并且生成修改列所需的SQL。

有时您需要优化JPA代码(但仅当您测量哪些操作很慢时)。经典的场景是批量删除/更新,您不希望JPA花费时间阅读/复制/管理您要删除/更新的实体。在这种情况下,您可以使用删除或更新查询,而不是加载实体并调用EntityManager.remove()或修改事务内的实体。但是,您应该意识到,这绕过EntityListeners和Cascade指令,因为这些说明仅被要求用于托管实体。

最新更新