@Modifying
前面的所有部分都描述了如何声明查询以访问给定的实体或实体集合。您可以使用Spring Data Repositories 的自定义实现中描述的自定义方法设施来添加自定义修改行为。由于这种方法对于全面的自定义功能是可行的,您可以通过使用@Modifying 注释查询方法来修改只需要参数绑定的查询,如下例所示:
示例 73. 声明操作查询
@Modifying @Query("update User u set u.firstname = ?1 where u.lastname = ?2") int setFixedFirstnameFor(String firstname, String lastname);
这样做会触发注解给方法的查询作为更新查询而不是选择查询。由于在执行修改查询后 EntityManager 可能包含过时的实体,我们不会自动清除它(有关详细信息,请参阅 EntityManager.clear() 的 JavaDoc),因为这有效地删除了 EntityManager 中仍未完成的所有未刷新更改。如果您希望自动清除 EntityManager,可以将 @Modifying 注解的 clearAutomatically 属性设置为 true。
@Modifying 注释仅与@Query 注释结合使用。派生查询方法或自定义方法不需要此注释。
派生删除查询
Spring Data JPA 还支持派生删除查询,让您不必显式声明 JPQL 查询,如以下示例所示:
例子 74. 使用派生的删除查询
interface UserRepository extends Repository<User, Long> { void deleteByRoleId(long roleId); @Modifying @Query("delete from User u where u.role.id = ?1") void deleteInBulkByRoleId(long roleId); }
尽管 deleteByRoleId(…) 方法看起来基本上产生与 deleteInBulkByRoleId(…) 相同的结果,但两种方法声明在运行方式方面存在重要差异。顾名思义,后一种方法针对数据库发出单个 JPQL 查询(注释中定义的查询)。这意味着即使当前加载的 User 实例也看不到调用的生命周期回调。
为了确保真正调用生命周期查询,调用 deleteByRoleId(...) 运行查询,然后一个一个地删除返回的实例,以便持久性提供程序可以实际调用这些实体上的@PreRemove 回调。
事实上,派生的删除查询是运行查询然后在结果上调用 CrudRepository.delete(Iterable<User> users) 并保持行为与 CrudRepository 中其他 delete(…) 方法的实现同步的快捷方式。
注意:在使用@Modifying注解时,如果忘了加 @Transactional注解可能会报错。
数据修改和删除,需要显示声明事务,否则会报错,一个是在调用的方法上添加注解 @Transactional,或者直接在repository api的接口上添加注解 @Transactional
(1)可以通过自定义的 JPQL 完成 UPDATE 和 DELETE 操作。注意:JPQL 不支持使用 INSERT;
(2)在 @Query 注解中编写 JPQL 语句,但必须使用 @Modifying 进行修饰. 以通知 SpringData,这是一个 UPDATE 或 DELETE 操作
(3)UPDATE 或 DELETE 操作需要使用事务,此时需要定义 Service 层,在 Service 层的方法上添加事务操作;
(4)默认情况下,SpringData 的每个方法上有事务,但都是一个只读事务。他们不能完成修改操作。
本文链接地址:Java Spring JPA @Modifying 用于修改,英雄不问来路,转载请注明出处,谢谢。
有话想说:那就赶紧去给我留言吧。
文章评论