使用休眠批量更新
Bulk update with hibernate
目前我们的 API 中有两个端点:
- 一个更新一个实体
- 要更新 一个 集合的 entity
字段的各种方法
第一个只使用saveOrUpdate休眠方法
而第二个创建自定义 HQL 查询以更新所需的字段。
我只想做一个端点。这个想法是接收代表实体的有效载荷。实体的每个不为空的字段都是我们应该更新的字段。
我想用这种方式来做,但它不起作用,因为 setParameter 可以设置不在字符串中的参数。
有什么想法吗?
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();
}
好的,用标准修复它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();
}
目前我们的 API 中有两个端点:
- 一个更新一个实体
- 要更新 一个 集合的 entity 字段的各种方法
第一个只使用saveOrUpdate休眠方法
而第二个创建自定义 HQL 查询以更新所需的字段。
我只想做一个端点。这个想法是接收代表实体的有效载荷。实体的每个不为空的字段都是我们应该更新的字段。
我想用这种方式来做,但它不起作用,因为 setParameter 可以设置不在字符串中的参数。 有什么想法吗?
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();
}
好的,用标准修复它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();
}