【发布时间】:2014-07-06 13:03:55
【问题描述】:
我正在使用 Spring JPA 进行数据库访问。我能够找到诸如 findByName 和 countByName 之类的示例,我不必为此编写任何方法实现。我希望找到根据某些条件删除一组记录的示例。
Spring JPA 是否支持类似 deleteByName 的删除?任何指针表示赞赏。
问候和感谢。
【问题讨论】:
标签: spring spring-data spring-data-jpa
我正在使用 Spring JPA 进行数据库访问。我能够找到诸如 findByName 和 countByName 之类的示例,我不必为此编写任何方法实现。我希望找到根据某些条件删除一组记录的示例。
Spring JPA 是否支持类似 deleteByName 的删除?任何指针表示赞赏。
问候和感谢。
【问题讨论】:
标签: spring spring-data spring-data-jpa
不推荐使用的答案(Spring Data JPA :
@Modifying 注释来救援。不过,您需要提供您的自定义 SQL 行为。
public interface UserRepository extends JpaRepository<User, Long> {
@Modifying
@Query("delete from User u where u.firstName = ?1")
void deleteUsersByFirstName(String firstName);
}
更新:
在 Spring Data JPA (>=1.7.x) 的现代版本中,delete、remove 和 count 操作的查询派生是可访问的。
public interface UserRepository extends CrudRepository<User, Long> {
Long countByFirstName(String firstName);
Long deleteByFirstName(String firstName);
List<User> removeByFirstName(String firstName);
}
【讨论】:
DELETE FROM x WHERE id = ?1 or parent_id = ?1 解决这个问题。顺便说一句,请确保您在parent__id 中没有类型(您是否有意使用双低破折号?)。你为什么要使用原生查询选项?
如果您查看 Spring Data JPA 的源代码,尤其是 PartTreeJpaQuery 类,您会看到它试图实例化 PartTree。
在该类中,以下正则表达式
private static final Pattern PREFIX_TEMPLATE = Pattern.compile("^(find|read|get|count|query)(\\p{Lu}.*?)??By")
应该指出什么是允许的,什么是不允许的。
当然,如果您尝试添加这样的方法,您实际上会发现它不起作用并且您会获得完整的堆栈跟踪。
我应该注意到我正在查看 Spring Data JPA 的 1.5.0.RELEASE 版本
【讨论】:
从 Spring Data JPA 的 1.6.0.RC1 版本开始支持使用给定方法名称派生删除查询。支持关键字remove 和delete。作为返回值,人们可以在数量或已删除实体列表之间进行选择。
Long removeByLastname(String lastname);
List<User> deleteByLastname(String lastname);
【讨论】:
如果您将使用 spring JPA 直接提供的预定义删除方法,那么框架将执行以下两个查询。
首先使用带删除查询where子句的执行选择查询收集数据(如id和其他列)。
然后在获得第一个查询的结果集后,将对所有 id 执行第二个删除查询(一个接一个)
注意:这不是为您的应用程序优化的方式,因为单个 MYSQL 删除查询将执行许多查询。
这是删除查询代码的另一种优化方式,因为使用以下自定义方法只会执行一个删除查询。
@NamedNativeQueries({
@NamedNativeQuery(name = "Abc.deleteByCreatedTimeBetween",
query = "DELETE FROM abc WHERE create_time BETWEEN ?1 AND ?2")
,
@NamedNativeQuery(name = "Abc.getByMaxId",
query = "SELECT max(id) from abc")
})
@Entity
public class Abc implements Serializable {
}
@Repository
public interface AbcRepository extends CrudRepository {
int getByMaxId();
@Transactional
@Modifying
void deleteByCreatedTimeBetween(String startDate, String endDate);
}
【讨论】:
使用派生查询进行批量删除时要小心。 这不是你所期望的:DeleteExecution
【讨论】:
两种方式:-
第一个自定义查询
@Modifying
@Query("delete from User where firstName = :firstName")
void deleteUsersByFirstName(@Param("firstName") String firstName);
第二个JPA查询方法
List<User> deleteByLastname(String lastname);
当您通过方法(第二种方式)进行查询时,它将首先进行 get 调用
select * from user where last_name = :firstName
然后它将它加载到一个列表中 然后会一一调用delete id
delete from user where id = 18
delete from user where id = 19
先获取对象列表,然后for循环逐个删除id
但是,第一个选项(自定义查询),
这只是一个查询 它将删除该值存在的任何位置。
由于第二个选项是进行多个数据库查询,请尝试使用第一个选项。
【讨论】:
是的,支持 deleteBy 方法 要使用它,您需要使用 @Transactional 注释方法
【讨论】:
下面是我的 2 美分。您还可以使用本机查询,例如:
@Modifying
@Query(value="delete from rreo r where r.cod_ibge = ?1 and r.exercicio= ?2", nativeQuery = true)
void deleteByParameters(Integer codIbge, Integer exercicio);
【讨论】:
@Query(value = "delete from addresses u where u.ADDRESS_ID LIKE %:addressId%", nativeQuery = true)
void deleteAddressByAddressId(@Param("addressId") String addressId);
【讨论】:
它只是工作
import org.springframework.transaction.annotation.Transactional;
@Transactional
Long removeAddressByCity(String city);
【讨论】: