Java spring数据jpa中的复杂快速更新
我有一个名为Java spring数据jpa中的复杂快速更新,java,hibernate,jpa,spring-data-jpa,Java,Hibernate,Jpa,Spring Data Jpa,我有一个名为Product的实体。它有几个字段,用户可以任意更新其中的一个或多个字段。对于更新产品s,我知道我可以从数据库中获取持久化产品,并更新它的字段,然后再次保存它,但这会导致真正的性能损失。更好的方法是在ProductRepostory界面中创建自定义更新查询,但在这种情况下,我应该为每个场景编写多个更新函数。我想得到更新字段及其值的映射,并编写一个按比例更新主题的查询 我听说Hibernate能够创建自定义的更新查询并像下面的代码一样执行 @Stateless @LocalBean p
Product
的实体。它有几个字段,用户可以任意更新其中的一个或多个字段。对于更新产品
s,我知道我可以从数据库中获取持久化产品,并更新它的字段,然后再次保存
它,但这会导致真正的性能损失。更好的方法是在ProductRepostory
界面中创建自定义更新查询,但在这种情况下,我应该为每个场景编写多个更新函数。我想得到更新字段及其值的映射,并编写一个按比例更新主题的查询
我听说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();
}
}
@无状态
@本地豆
公共类订单管理{
@持久上下文
私人实体管理者;
...
公共作废更新订单(双倍旧金额,双倍新金额){
CriteriaBuilder cb=this.em.getCriteriaBuilder();
//创建更新
CriteriaUpdate=cb。
createCriteriaUpdate(Order.class);
//设置根类
Root e=update.from(Order.class);
//set update和where子句
update.set(“金额”,newAmount);
更新。其中(cb.greaterThanOrEqualTo(e.get(“金额”),oldAmount));
//执行更新
this.em.createQuery(update.executeUpdate();
}
}
但我想知道如何在SpringDataJPA环境中使用它,最大的问题是如何获得entityManager实例,下一个问题是将此功能放在哪里最合适ProductRepostory
接口或某些自定义接口,如果答案是自定义接口,如何注册?好的,问这个问题的主要原因是一个错误的假设,我认为获取和更新程序中的实体可能会导致性能问题,但正如@jbniset所提到的,通过id获取实体很快,而且Hibernate还处理实体上的持久性更改,不需要手动调用save
简而言之,提出保存托管实体的新方法是没有帮助的,最好避免手动更新实体,但是如果想要手动扩展Jpa存储库,正如在评论中提到的那样,这里有一些解释。您可以在上面的链接中找到Spring数据中的自定义存储库。也可以像这样注入Entity manager<代码>@PersistenceContext EntityManager EntityManager代码>1。您不需要再次保存它:Hibernate会为您保存它。2.不,这不会造成任何真正的性能损失。通过ID读取表中的行非常快。你在过早地优化,这是所有邪恶的根源。您的代码将变得更加复杂,对于想象中的性能增益来说,安全性将降低。@JBNizet我必须说我是您的忠实粉丝。你是说每次我更新一个实体的字段时,hibernate会自动将其持久化吗?不调用保存
?这是默认行为还是必须手动启用?是的,这是默认行为,您无需对此做任何操作。托管实体(即您在事务中持久化的实体,或使用实体管理器、JPQL查询或通过浏览其他托管实体的关联获得的实体)是。。。由JPA管理。将检查它们的状态,如果状态已更改,JPA会在需要时(在提交之前,或在其结果可能受新状态影响的查询之前)将其保存在DB中。