【发布时间】:2017-07-25 06:09:51
【问题描述】:
我有一个名为 Product 的实体。它有几个字段,用户可以任意更新它的一个或多个字段。对于更新Products,我知道我可以从数据库中获取持久化产品并更新它的字段并再次更新save,但这会导致真正的性能损失。更好的方法是在ProductRepostory 接口中创建自定义更新查询,但在这种情况下,我应该为每个场景编写多个更新函数。我想获得更新字段及其值的Map<String,Object>,并编写一个查询以按比例更新主题。
我听说 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();
}
}
但是我想知道如何在spring data jpa的情况下使用这个,最大的问题是如何获取entityManager实例,接下来是哪里最适合放置这个功能? ProductRepostory接口或者一些自定义接口,如果回答是自定义接口,如何注册?
【问题讨论】:
-
dzone.com/articles/… 可以在上面的链接中找到 Spring Data 中的自定义存储库。
-
也可以像这样注入实体管理器。
@PersistenceContext EntityManager entityManager; -
1.您无需再次保存它:Hibernate 为您完成了这项工作。 2. 不,这不会导致任何真正的性能损失。通过 ID 读取表中的一行非常快。你过早地优化,这是万恶之源。您的代码将变得更加复杂,并且对于想象中的性能提升更不安全。
-
@JBNizet 我必须说我是你的忠实粉丝。您是说每次我更新实体的字段时,休眠都会自动保持它吗?不打电话给
save?这是默认行为还是必须手动启用? -
是的,这是默认行为,您无需对此进行任何操作。托管实体(即您在事务中持久保存的实体,或使用实体管理器获得的实体,或使用 JPQL 查询,或通过浏览其他托管实体的关联)...由 JPA 管理。检查它们的状态,如果它发生了变化,JPA 会在需要时将其保存在数据库中(在提交之前,或者在结果可能受新状态影响的查询之前)。
标签: java hibernate jpa spring-data-jpa