Spring Data JPA 的 @Modifying 在不指定其属性的情况下是否有任何用处?
Is there any use for Spring Data JPA's @Modifying without specifying it's attributes?
AFAIK @Modifying
在 @Query
注释中指定的 INSERT/UPDATE/DELETE 查询的情况下负责持久性上下文清理。
但是 pure @Modifying
有什么用呢?根据 ,似乎你应该总是写 @Modifying(clearAutomatically=true, flushAutomatically=true)
.
文档说(link):
As the EntityManager might contain outdated entities after the execution of the modifying query, we do not automatically clear it ... since this effectively drops all non-flushed changes still pending in the EntityManager
所以默认情况下 @Modifying
不清理(和 do not flush)。那我为什么要把它添加到我的 @Query
方法中呢?
(clearAutomatically=true, flushAutomatically=true) 它们将被添加以使用 clearAutomatically 和 flushAutomatically 属性来管理持久性上下文的状态。
这将 clear/flush 一级缓存中的对象。
通过使用 @修改 spring 引导应用程序向 DB 授予写入权限以执行这些操作 (UPDATE/INSERT/DELETE)。
@Query可以单独使用做GET,其他3个修改操作必须使用@modify才能获得DB权限。
@Query
s 上的写操作是强制性的,这就是原因。
clearAutomatically 和 flushAutomatically 分别允许您决定是否在之后立即清除和在之前立即刷新。如果设置为 false(默认值),那么 Spring Data 将在它认为合适的时候执行此操作,尝试优化对数据库的访问操作。操作后可能不清除,或操作前刷新,但它仍然会。
@Modifying 注释用于增强@Query 注释,不仅可以执行 SELECT 查询,还可以执行 INSERT、UPDATE、DELETE,甚至 DDL 查询。
让我们稍微研究一下这个注释,看看它是由什么组成的。
首先,让我们看一个@Modifying UPDATE 查询的例子:
@Modifying
@Query("update User u set u.active = false where u.lastLoginDate < :date")
void deactivateUsersNotLoggedInSince(@Param("date") LocalDate date);
让我们尝试另一个删除停用用户的方法:
@Modifying
@Query("delete User u where u.active = false")
int deleteDeactivatedUsers();
我们可以看到,这个方法returns一个整数。这是 Spring Data JPA @Modifying 查询的一项功能,它为我们提供了更新实体的数量。
我们应该注意,使用@Query 执行删除查询的工作方式不同于 Spring Data JPA 的 deleteBy 名称派生查询方法。后者先从数据库中取出实体,然后一个一个删除。因此,这意味着将在这些实体上调用生命周期方法@PreRemove。但是,对于前者,对数据库执行单个查询。
最后,让我们使用 DDL 查询向我们的 USERS table 添加一个已删除的列:
@Modifying
@Query(value = "alter table USERS.USERS add column deleted int(1) not null default 0", nativeQuery = true)
void addDeletedColumn();
不幸的是,使用修改查询会使底层持久性上下文过时。但是,可以管理这种情况。
AFAIK @Modifying
在 @Query
注释中指定的 INSERT/UPDATE/DELETE 查询的情况下负责持久性上下文清理。
但是 pure @Modifying
有什么用呢?根据 @Modifying(clearAutomatically=true, flushAutomatically=true)
.
文档说(link):
As the EntityManager might contain outdated entities after the execution of the modifying query, we do not automatically clear it ... since this effectively drops all non-flushed changes still pending in the EntityManager
所以默认情况下 @Modifying
不清理(和 do not flush)。那我为什么要把它添加到我的 @Query
方法中呢?
(clearAutomatically=true, flushAutomatically=true) 它们将被添加以使用 clearAutomatically 和 flushAutomatically 属性来管理持久性上下文的状态。 这将 clear/flush 一级缓存中的对象。
通过使用 @修改 spring 引导应用程序向 DB 授予写入权限以执行这些操作 (UPDATE/INSERT/DELETE)。 @Query可以单独使用做GET,其他3个修改操作必须使用@modify才能获得DB权限。
@Query
s 上的写操作是强制性的,这就是原因。
clearAutomatically 和 flushAutomatically 分别允许您决定是否在之后立即清除和在之前立即刷新。如果设置为 false(默认值),那么 Spring Data 将在它认为合适的时候执行此操作,尝试优化对数据库的访问操作。操作后可能不清除,或操作前刷新,但它仍然会。
@Modifying 注释用于增强@Query 注释,不仅可以执行 SELECT 查询,还可以执行 INSERT、UPDATE、DELETE,甚至 DDL 查询。
让我们稍微研究一下这个注释,看看它是由什么组成的。
首先,让我们看一个@Modifying UPDATE 查询的例子:
@Modifying
@Query("update User u set u.active = false where u.lastLoginDate < :date")
void deactivateUsersNotLoggedInSince(@Param("date") LocalDate date);
让我们尝试另一个删除停用用户的方法:
@Modifying
@Query("delete User u where u.active = false")
int deleteDeactivatedUsers();
我们可以看到,这个方法returns一个整数。这是 Spring Data JPA @Modifying 查询的一项功能,它为我们提供了更新实体的数量。
我们应该注意,使用@Query 执行删除查询的工作方式不同于 Spring Data JPA 的 deleteBy 名称派生查询方法。后者先从数据库中取出实体,然后一个一个删除。因此,这意味着将在这些实体上调用生命周期方法@PreRemove。但是,对于前者,对数据库执行单个查询。
最后,让我们使用 DDL 查询向我们的 USERS table 添加一个已删除的列:
@Modifying
@Query(value = "alter table USERS.USERS add column deleted int(1) not null default 0", nativeQuery = true)
void addDeletedColumn();
不幸的是,使用修改查询会使底层持久性上下文过时。但是,可以管理这种情况。