首页 文章

Spring Data:支持“删除”吗?

提问于
浏览
78

我使用Spring JPA进行数据库访问 . 我能够找到像findByName和countByName这样的例子,我没有必要编写任何方法实现 . 我希望找到基于某些条件删除一组记录的示例 .

Spring JPA是否支持deleteByName-like delete?任何指针都很受欢迎 .

问候和感谢 .

5 回答

  • 59

    不推荐的答案(Spring Data JPA <= 1.6.x):

    @Modifying 拯救注释 . 您需要提供自定义SQL行为 .

    @Transactional(readOnly = true)
    public interface UserRepository extends JpaRepository<User, Long> {
        @Modifying
        @Transactional
        @Query("delete from User u where u.firstName = ?1")
        void deleteUsersByFirstName(String firstName);
    }
    

    更新:

    在现代版本的Spring Data JPA(> = 1.7.x)中,可以访问 deleteremovecount 操作的查询派生 .

    public interface UserRepository extends CrudRepository<User, Long> {
    
        Long countByFirstName(String firstName);
    
        @Transactional
        Long deleteByFirstName(String firstName);
    
        @Transactional
        List<User> removeByFirstName(String firstName);
    
    }
    
  • 0

    从Spring Data JPA的版本1.6.0.RC1开始,支持使用给定方法名称派生删除查询 . 支持关键字 removedelete . 作为返回值,可以在数字或已删除实体列表之间进行选择 .

    Long removeByLastname(String lastname);
    
    List<User> deleteByLastname(String lastname);
    
  • 6

    如果你看一下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

  • 161

    如果您将使用spring JPA直接提供的预定义删除方法,那么框架将执行以下两个查询 .

    • 首先使用带有delete query where子句的execute select query来收集数据(如id和其他列) .

    • 然后获取第一个查询的resultSet后,将对所有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);
    }
    
  • 0

    使用派生查询进行批量删除时要小心 . 这不是你所期望的:DeleteExecution

相关问题