2017-07-25 94 views
0

我有一个名为Product的实体。它有几个字段,用户可以任意更新一个或多个字段。为了更新Product s,我知道我可以从数据库获得持久性产品并更新它的字段并再次使用它,但这会导致真正的性能损失。更好的方法是在ProductRepostory接口中创建自定义更新查询,但在这种情况下,我应该为每个方案编写多个更新函数。我想获得更新字段及其值的Map<String,Object>,并编写查询以按比例更新主题。春季数据复杂和快速更新jpa

听说Hibernate必须创建自定义更新查询,并执行类似下面的代码

@Stateless 
@LocalBean 
public class OrderManagement { 
    @PersistenceContext 
    private EntityManager em; 

    ... 

    public void updateOrder(Double oldAmount, Double newAmount) { 
     CriteriaBuilder cb = this.em.getCriteriaBuilder(); 

     // create update 
     CriteriaUpdate<Order> update = cb. 
     createCriteriaUpdate(Order.class); 

     // set the root class 
     Root e = update.from(Order.class); 

     // set update and where clause 
     update.set("amount", newAmount); 
     update.where(cb.greaterThanOrEqualTo(e.get("amount"), oldAmount)); 

     // perform update 
     this.em.createQuery(update).executeUpdate(); 
    } 

} 

的能力,但我不知道如何在春季数据JPA的情况下使用,最大的问题是如何获得的EntityManager实例,下一个是哪里是最适合放置此功能的地方? ProductRepostory界面或一些自定义界面,如果答案是自定义界面,如何注册?

+0

https://dzone.com/articles/add-custom-functionality-to-a-spring-data-reposito 您可以在上面的链接中的Spring Data中找到自定义存储库。 –

+0

也可以像这样注入实体管理器。 '@PersistenceContext EntityManager entityManager;' –

+1

1.您不需要再次保存它:Hibernate为您做到了这一点。 2.这不会导致任何实际的表现损失。通过ID读取表中的行非常快。你正在过早地优化,这是所有邪恶的根源。你的代码将变得更复杂,并且对于想象中的性能增益而言不太安全。 –

回答

0

好的,问这个问题的主要原因是一个错误的假设,我认为在程序中获取和更新实体可能会导致性能问题,但正如@JBNizet所提到的,通过id获取实体的速度很快,而且Hibernate处理Entity上的持续更改,无需手动拨打save

因此,作为概括地说,提出节能管理的实体的新方法是没有帮助的,这是更好地避免UPDATE实体手动,但如果一个人想手动扩展JPA库,有nice article解释它已经提到在评论中。