简体   繁体   English

使用 hibernate 批量更新

[英]Bulk update with hibernate

Currently we have two endpoints in our API:目前我们的 API 有两个端点:

  • One to update one entity一个更新一个实体
  • An various ones to update one field of a Collection of entity更新实体集合的一个字段的各种方法

The first one only use saveOrUpdate method of hibernate第一个只使用 hibernate 的saveOrUpdate方法

While the second one create a custom HQL query to update the desired field.而第二个创建一个自定义 HQL 查询来更新所需的字段。

I would like to make only one endpoint.我只想做一个端点。 The idea would be receiving a payload representing the entity.这个想法是接收代表实体的有效载荷。 Each field of the entity that are not null would be field that we should update.不是 null 的实体的每个字段都是我们应该更新的字段。

I wanted to do that in this way, but it doesn't work as setParameter could set parameters that are not in the String.我想用这种方式来做,但它不起作用,因为 setParameter 可以设置不在字符串中的参数。 Any ideas?有任何想法吗?

  public long update(Collection<Long> toUpdate, SaleItemDTO newValues) {
    if (toUpdate.size() == 0) return 0;
    StringBuilder hql = new StringBuilder("UPDATE SaleItem SET ");
    if (!newValues.getName().isEmpty()) hql.append("name = :name,");
    if (newValues.getPrice() != null) hql.append("price = :price,");
    if (newValues.getTag() != null) hql.append("tag = :tag,");
    if (newValues.getCategory() != null) hql.append("category.id = :categoryId,");
    if (newValues.isRecurringSale() != null) hql.append("isRecurringSale = :isRecurringSale,");
    if (newValues.isCallProduct() != null) hql.append("callProduct = :callProduct,");
    hql.deleteCharAt(hql.length() - 1).append(" WHERE id in :ids");
    
    return this.sessionFactory
        .getCurrentSession()
        .createQuery(hql.toString())
        .setParameter("name", newValues.getName())
        .setParameter("price", newValues.getPrice())
        .setParameter("tag", newValues.getTag())
        .setParameter("categoryId", newValues.getCategory().getId())
        .setParameter("isRecurringSale", newValues.isRecurringSale())
        .setParameter("callProduct", newValues.isCallProduct())
        .setParameter("ids", toUpdate)
        .executeUpdate();
  }

Okay, fix it with Criteria API好的,用标准修复它 API

  public long update(Collection<Long> toUpdate, SaleItemDTO newValues) {
    if (toUpdate.size() == 0) return 0;
    CriteriaBuilder criteriaBuilder = this.sessionFactory.getCriteriaBuilder();
    // create update
    CriteriaUpdate<SaleItem> update = criteriaBuilder.createCriteriaUpdate(SaleItem.class);
    // set the root class
    Root<SaleItem> saleItemRoot = update.from(SaleItem.class);
    // set update and where clause
    if (!newValues.getName().isEmpty()) update.set("name", newValues.getName());
    if (newValues.getPrice() != null) update.set("price", newValues.getPrice());
    //if (newValues.getCategory() != null) update.set("category.id", newValues.getCategory().getId());
    if (newValues.getTag() != null) update.set("tag", newValues.getTag());
    if (newValues.isRecurringSale() != null) update.set("isRecurringSale", newValues.isRecurringSale());
    if (newValues.isCallProduct() != null) update.set("callProduct", newValues.getProduct());
    update.where(saleItemRoot.get("id").in(toUpdate));

    return this.sessionFactory.getCurrentSession().createQuery(update).executeUpdate();
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM