Spring Data JPA常用查询方法的定义使用

一、以下示例显示了 JPA 查询方法转换为的内容:
public interface UserRepository extends Repository<User, Long> {
List findByEmailAddressAndLastname(String emailAddress, String lastname);
}
我们使用 JPA 标准 API 从中创建一个查询,但本质上,这会转换为以下查询:select u from User u where u.emailAddress = ?1 and u.lastname = ?2

下表描述了JPA支持的关键字以及包含该关键字的方法转换为什么:
在这里插入图片描述

在这里插入图片描述
二、使用@Query查询
1.以下示例显示了使用@Query注解创建的查询
public interface UserRepository extends JpaRepository<User, Long> {

//在查询方法上声明查询使用 @Query
@Query(“select u from User u where u.emailAddress = ?1”)
User findByEmailAddress(String emailAddress);
}
2.使用@query创建的手动定义查询的查询运行机制允许在查询定义中定义高级(LIKE)表达式如下例所示:
public interface UserRepository extends JpaRepository<User, Long> {

@Query(“select u from User u where u.firstname like %?1”)
List findByFirstnameEndsWith(String firstname);
}
示例中,LIKE分隔符 ( %) 被识别,并将查询转换为有效的 JPQL 查询(删除%)。
3.本机查询
@Query注解允许通过将nativeQuery标志设置为true来运行本机查询,如下例所示:
使用 @Query 在查询方法上声明本机查询
public interface UserRepository extends JpaRepository<User, Long> {

@Query(value = “SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1”, nativeQuery = true)
User findByEmailAddress(String emailAddress);
}
注:Spring Data JPA目前不支持本机查询的动态排序,因为它必须操作所声明的实际查询,这对于本机SQL来说是不可靠的。但是,您可以通过自己指定计数查询来使用本机查询进行分页,如下例所示:
public interface UserRepository extends JpaRepository<User, Long> {

@Query(value = “SELECT * FROM USERS WHERE LASTNAME = ?1”,
countQuery = “SELECT count(*) FROM USERS WHERE LASTNAME = ?1”,
nativeQuery = true)
Page findByLastname(String lastname, Pageable pageable);
}
4.使用命名参数
默认情况下,Spring Data JPA 使用基于位置的参数绑定,如前面所有示例中所述。这使得在重构参数位置时查询方法有点容易出错。为了解决这个问题,您可以使用@Param注解给方法参数一个具体的名称并在查询中绑定名称,如下例所示:
public interface UserRepository extends JpaRepository<User, Long> {

@Query(“select u from User u where u.firstname = :firstname or u.lastname = :lastname”)
User findByLastnameOrFirstname(@Param(“lastname”) String lastname,
@Param(“firstname”) String firstname);
}
5.修改查询
前面的所有部分都描述了如何声明查询以访问给定的实体或实体集合。您可以使用“ Spring Data Repositories 的自定义实现”中描述的自定义方法工具添加自定义修改行为。由于这种方法对于全面的自定义功能是可行的,您可以通过使用@Modifying 注释查询方法来修改只需要参数绑定的查询
如下实例:
@Modifying
@Query(“update User u set u.firstname = ?1 where u.lastname = ?2”)
int setFixedFirstnameFor(String firstname, String lastname);

如此做会触发被注解查询的方法作为一个更新查询而不是选择查询
注:@Modifying注解是唯一与@Query注解组合相关的。派生查询方法或自定义方法不需要此注解。
6.派生删除查询
Spring Data JPA 还支持派生删除查询,让您不必显式声明 JPQL 查询
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查询(注释中定义的查询)。这意味着即使是当前加载的用户实例也看不到调用的生命周期回调。为了确保实际调用了生命周期查询,对deleteByRoleId(…)的调用将运行一个查询,然后逐个删除返回的实例,以便持久性提供程序可以实际调用这些实体上的@PreRemove回调。事实上,派生的delete查询是一种快捷方式,用于运行查询,然后对结果调用crudepository.delete(Iterableusers),并使行为与crudepository中其他delete(…)方法的实现保持同步。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

改啥名不重复

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值