Spring JPA 查询创建
Spring JPA 查询创建
这是JPA内容的核心部分,可以收藏用作参阅文档。
1. 查询转化和关键字
例:一个JPA查询的转化
public interface UserRepository extends Repository<User, Long> {
List<User> findByEmailAddressAndLastname(String emailAddress, String lastname);
}
我们使用JPA 标准API创建一个查询,但从本质上讲,这将转换为以下查询:select u from User u where u.emailAddress = ?1 and u.lastname = ?2,Spring Data JPA执行属性检查并遍历嵌套属性,如属性表达式中所述。
下表描述了JPA支持的关键字,以及包含该关键字的方法可以转换成什么查询语句:
表:查询关键字及对应查询语句
| 关键字 | 样例 | JPQL片段(转化的查询语句) |
|---|---|---|
And |
findByLastnameAndFirstname |
… where x.lastname = ?1 and x.firstname = ?2 |
Or |
findByLastnameOrFirstname |
… where x.lastname = ?1 or x.firstname = ?2 |
Is, Equals |
findByFirstname,findByFirstnameIs,findByFirstnameEquals |
… where x.firstname = ?1 |
Between |
findByStartDateBetween |
… where x.startDate between ?1 and ?2 |
LessThan |
findByAgeLessThan |
… where x.age < ?1 |
LessThanEqual |
findByAgeLessThanEqual |
… where x.age <= ?1 |
GreaterThan |
findByAgeGreaterThan |
… where x.age > ?1 |
GreaterThanEqual |
findByAgeGreaterThanEqual |
… where x.age >= ?1 |
After |
findByStartDateAfter |
… where x.startDate > ?1 |
Before |
findByStartDateBefore |
… where x.startDate < ?1 |
IsNull, Null |
findByAge(Is)Null |
… where x.age is null |
IsNotNull, NotNull |
findByAge(Is)NotNull |
… where x.age not null |
Like |
findByFirstnameLike |
… where x.firstname like ?1 |
NotLike |
findByFirstnameNotLike |
… where x.firstname not like ?1 |
StartingWith |
findByFirstnameStartingWith |
… where x.firstname like ?1 (参数绑定附加 %) |
EndingWith |
findByFirstnameEndingWith |
… where x.firstname like ?1 (参数绑定附加 %) |
Containing |
findByFirstnameContaining |
… where x.firstname like ?1 (参数绑定附加 %) |
OrderBy |
findByAgeOrderByLastnameDesc |
… where x.age = ?1 order by x.lastname desc |
Not |
findByLastnameNot |
… where x.lastname <> ?1 |
In |
findByAgeIn(Collection<Age> ages) |
… where x.age in ?1 |
NotIn |
findByAgeNotIn(Collection<Age> ages) |
… where x.age not in ?1 |
True |
findByActiveTrue() |
… where x.active = true |
False |
findByActiveFalse() |
… where x.active = false |
IgnoreCase |
findByFirstnameIgnoreCase |
… where UPPER(x.firstame) = UPPER(?1) |
In和NotIn也接受集合的任何子类以及数组作为一个参数或可变参数。对于相同逻辑运算符的其他语法版本,请检查存储库查询关键字。
2. 使用@Query 自定义查询
使用自命名查询声明实体的查询是一种有效的方法,该方法适用于少量查询。由于查询本身绑定到执行它们的Java方法上,实际上可以通过使用Spring Data JPA @Query注释直接绑定,而不用将它们注释到域类。这将域类从特定于持久性的信息中解放出来,并将查询合并到该存储库接口:
注释@Query查询优先于使用@NamedQuery定义的查询和在orm.xml中声明的自命名查询。
例:使用@Query在查询方法上声明查询
public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);
}
3. 使用高级LIKE表达式
使用@Query创建的自命名查询的查询执行机制允许在查询定义中定义高级LIKE表达式,如下面的示例所示:
例:@Query中定义的LIKE表达式
public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where u.firstname like %?1")
List<User> findByFirstnameEndsWith(String firstname);
}
在前面的示例中,识别了LIKE的分隔符字符(%),并将查询转换为有效的JPQL查询(移除%)。在执行查询时,传递给方法调用的参数将使用之前识别的LIKE模式进行扩充。
4. 使用原生查询
将nativeQuery标志设置为true, @Query注释允许运行原生查询,如下面的示例所示:
例:使用@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来说是不可靠的。但是,您可以通过自己指定count查询来对本机查询的结果进行分页,如下面的示例所示:
例:通过使用@Query在查询方法上声明用于分页的本机计数查询
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<User> findByLastname(String lastname, Pageable pageable);
}
5.使用Sort
我们可以通过PageRequest和Sort直接完成排序,Sort的Order实例中实际使用的属性需要与您的域模型(持久化模型)匹配。这意味着它们需要解析为查询中使用的属性或别名。JPQL将其定义为状态字段路径表达式。
使用任何不可引用的路径表达式都会导致异常。
但是,使用Sort和@Query可以让您插入包含Order BY子句在内的函数非路径检查的Order实例,您可以使用JpaSort。添加可能不安全的排序。
例:使用Sort和JpaSort
public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where u.lastname like ?1%")
List<User> findByAndSort(String lastname, Sort sort);
@Query("select u.id, LENGTH(u.firstname) as fn_len from User u where u.lastname like ?1%")
List<Object[]> findByAsArrayAndSort(String lastname, Sort sort);
}
repo.findByAndSort("lannister", new Sort("firstname")); //在域模型中指向属性的有效排序表达式
repo.findByAndSort("stark", new Sort("LENGTH(firstname)")); //包含函数调用的无效排序。Thows 异常
repo.findByAndSort("targaryen", JpaSort.unsafe("LENGTH(firstname)")); //包含显式不安全顺序的有效排序。
repo.findByAsArrayAndSort("bolton", new Sort("fn_len")); //指向别名函数的有效排序表达式。
6.使用(自)命名参数
默认情况下,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);
}
这样子就不需要再保证位置的一一对应了,只需要保证名称的对应即可,方法参数根据它们在定义的查询中的顺序进行切换
参考文档
1.翻译:【JPA Query Methods】
Spring JPA 查询创建的更多相关文章
- spring data jpa 查询自定义字段,转换为自定义实体
目标:查询数据库中的字段,然后转换成 JSON 格式的数据,返回前台. 环境:idea 2016.3.4, jdk 1.8, mysql 5.6, spring-boot 1.5.2 背景:首先建立 ...
- Spring JPA 定义查询方法
Spring JPA 定义查询方法 翻译:Defining Query Methods 存储库代理有两种方式基于方法名派生特定域的查询方式: 直接从方法名派生查询 自定义查询方式 可用选项基于 ...
- Spring JPA使用CriteriaBuilder动态构造查询
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://www.cnblogs.com/mzdljgz/p/11495723. ...
- spring jpa 自定义查询数据库的某个字段
spring jpa 提供的查询很强大, 就看你会不会用了. 先上代码, 后面在解释吧 1. 想查单个表的某个字段 在repository中 @Query(value = "select i ...
- spring data jpa查询部分字段、多余附加字段
spring data jpa查询部分字段 第一种方法:使用 model 查询时转化 首先建立一个 model ,写上自己想要查询的字段,然后写上构造函数,这步很重要,因为spring jpa 转化时 ...
- Spring JPA学习笔记
目录 什么是JPA? 引入配置 新建一个Entity Bean类 JPA的增删改查 新建操作接口 新建测试类 总结 什么是JPA? 什么是JDBC知道吧?数据库有Mysql,SQL Server,Or ...
- 使用Spring JPA中Page、Pageable接口和Sort类完成分页排序
显示时,有三个参数,前两个必填,第几页,一页多少个size,第三个参数默认可以不填. 但是发现这个方法已经过时了,通过查看它的源码发现,新方法为静态方法PageRequest of(page,size ...
- spring jpa和mybatis整合
spring jpa和mybatis整合 前一阵子接手了一个使用SpringBoot 和spring-data-jpa开发的项目 后期新加入一个小伙伴,表示jpa相比mybatis太难用,多表联合的查 ...
- spring.jpa.open-view问题
由ReentrantLock和JPA(spring.jpa.open-in-view)导致的死锁问题原因分析. 问题 在压测过程中,发现服务经过一段时间压测之后出现无响应,且无法自动恢复. 分析 从上 ...
随机推荐
- ACL权限管理 学习
#查看权限 getfacl 文件名 例子:getfacl test 结果:# file: test# owner: root# group: rootuser::rw-group::r-xother: ...
- 内存总是不够?HBase&GeoMesa配置优化了解一下
概况: 生产环境HBase集群内存经常处于高位(90%),而且GC之后也是内存依然处于高位,经分析内存全部由集群的regionserver进程所持有,,经常重启之后,大概3-4天就会保持在高位.由上述 ...
- 2020-06-19:多线程消费kafka的时候,开发、测试环境都能每秒10w+,但是正式环境只能1w/s,正式环境不能重启,看怎么调试?
福哥答案2020-06-19: 答案来自群成员:基准测试. 观察 网络和磁盘的读写,实时与历史曲线,观察文件句柄/内存的使用情况.观察系统patch 基础库/运行时状态.
- C#LeetCode刷题之#263-丑数(Ugly Number)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3862 访问. 编写一个程序判断给定的数是否为丑数.丑数就是只包含 ...
- 2、java数据类型转换
当数据类型不一样时,将会发生数据类型转换. 1.自动类型转换(隐式) 1. 特点:代码不需要进行特殊处理,自动完成. 2. 规则:数据范围从小到大. System.out.println(1024); ...
- 大侠稍等!URL 中为何出现奇怪的字符
为什么中文名称的图片打开后网址是一串乱码?为什么好好的短网址复制粘贴就变长了一大长串?罪魁祸首居然是-- 杭州终于出梅了!二狗子看到气象台发布的消息,开心的不得了.杭州的雨从五月底一直下,每天除了雨还 ...
- 兼容ie9上传本地资源
在ie9中上传文件出现问题,大多数的上传文件都采用new Formdata创建添加文件,在IE9中不支持Formdata对象操作,ie10是支持的.所以只能使用表单提交的方式进行操作. <for ...
- Jmeter系列(51)- 详解 Transaction Controller 事务控制器
如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 简单介绍 可以添加多个取样器(samp ...
- 测试和发布说明(Alpha版本)
Alpha版本测试报告 1.测试中发现的BUG 已修复 服务器无法发送邮件 重复上传同一首歌曲 下载进度无法实时跟进 可以多次点击上传 注册验证码失真 上传结束无法及时清理队列信息 不可重现的BUG ...
- Synergy--跨平台的键鼠共享工具
目前的状态,Windows并没有彻底放弃使用,现在一个电脑桌上摆放了一台Mac pro 一台Windows,两个笔记本都是15寸的,如果想要方便的使用外设鼠标键盘,整个桌子会异常的臃肿,鼠标键盘太占地 ...