【问题标题】:Why can JPQLs modifying queries only return void or int?为什么 JPQL 修改查询只能返回 void 或 int?
【发布时间】:2020-04-12 21:22:33
【问题描述】:

当我想通过 JPQL 修改数据库时,我必须将查询标记为 TransactionalModiyfing。如果我这样做,表示查询的方法的返回类型必须是voidint(表示我认为的已编辑行数)。为什么只允许两种返回类型?如果我执行 HTTP-PUT 请求并使用自己的 JPQL 查询更新对象,我想再次返回更新后的对象。如果查询的返回类型必须是voidint,那么最好的方法是什么?我是否必须再次执行单独的查询/请求来选择更新后的对象?

编辑:

这就是我调用查询的方式:

if (inactivityListDTO.getProjectIds().size() > 0) {
  projectRepository.updateProjectsIsArchivedByProjectIds(inactivityListDTO.getProjectIds(), inactivityListDTO.getIsArchived());
}

这是查询:

@Transactional
@Modifying
@Query("UPDATE Project project SET project.isArchived = :isArchived, 
       project.archivedDate = current_date " +
       "WHERE project.id IN :ids")
void updateProjectsIsArchivedByProjectIds(@Param("ids") List<Long> ids, @Param("isArchived") boolean isArchived);

【问题讨论】:

    标签: spring jpql


    【解决方案1】:

    因为最终归结为在 DB 中执行标准的UPDATE SQL,而标准 SQL 中的 UPDATE 只返回正在更新的记录数,不返回结果集。

    是的,如果您需要在更新后获取记录的值,则必须再次查询。或者,您应该考虑使用 JPA 方式来更新记录,它首先查询对象,然后通过更改其状态来更新它。类似于下面的内容(假设您使用 spring @Transactional 来管理事务边界)

    @Transactional
    public void changeEmployeeSalary(Integer employeeId , Integer salary){
        Employee employee = entityManager.find(Employee.class , employeeId);
        employee.setSalary(salary);
    }
    

    这样,更新后就不需要再查询记录,也不需要手动编写UPDATE SQL。

    【讨论】:

    • 我不使用通常的 JPA 更新方法的原因是我想更新列表中的多个对象。如果我执行上面的 JPA 方法,我将不得不遍历列表并更新其中的每个对象,如果 N 是列表的大小,则会导致 N 个查询。这减慢了我的应用程序,因为对数据库的每个查询都有 5 毫秒的 ping。所以我决定编写自己的查询,只需一个查询即可更新列表中的所有对象。可能有一种方法可以在一个查询中更新多个对象(行)而无需编写自己的查询,但我没有找到方法。
    • 我展示的只是展示这个想法的一个例子。在您的情况下,您可以使用查询在一个查询中获取对象列表,这样您就不需要在 N 次中获取它。
    • 是的,在我的情况下,我可以只执行一个查询来更新列表中的所有对象,然后执行另一个查询以再次获取更新对象的列表。我只是想知道您是否知道一种在一个查询中更新列表中的多个对象而无需编写自己的查询的方法。我在上面发布了我的代码,是否可以在没有自己的查询的情况下实现相同的目标?
    • 要通过 ID 检索项目列表,您必须编写 JPQL 。在您的情况下,编写 select project from Project project where project.id in :ids 并不难。或者您可以使用 JPA 存储库中内置的 spring-data,它已经提供了一个方法调用 findAllById 来通过 ID 列表获取实体列表。
    猜你喜欢
    • 2020-02-15
    • 2018-03-03
    • 2013-01-08
    • 1970-01-01
    • 2014-08-02
    • 2019-03-07
    相关资源
    最近更新 更多