【JPA】表达条件查询的关键字
1.通过解析方法名创建查询
框架在进行方法名解析时,会先把方法名多余的前缀截取掉,比如 find、findBy、read、readBy、get、getBy,然后对剩下部分进行解析。并且如果方法的最后一个参数是 Sort 或者 Pageable 类型,也会提取相关的信息,以便按规则进行排序或者分页查询。
在创建查询时,我们通过在方法名中使用属性名称来表达,比如 findByUserAddressZip ()。框架在解析该方法时,首先剔除 findBy,然后对剩下的属性进行解析,详细规则如下(此处假设该方法针对的域对象为 AccountInfo 类型):
- 先判断 userAddressZip (根据 POJO 规范,首字母变为小写,下同)是否为 AccountInfo 的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,继续第二步;
- 从右往左截取第一个大写字母开头的字符串(此处为 Zip),然后检查剩下的字符串是否为 AccountInfo 的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设 user 为 AccountInfo 的一个属性;
- 接着处理剩下部分( AddressZip ),先判断 user 所对应的类型是否有 addressZip 属性,如果有,则表示该方法最终是根据 "AccountInfo.user.addressZip" 的取值进行查询;否则继续按照步骤 2 的规则从右往左截取,最终表示根据 "AccountInfo.user.address.zip" 的值进行查询。
在查询时,通常需要同时根据多个属性进行查询,且查询的条件也格式各样(大于某个值、在某个范围等等),Spring Data JPA 为此提供了一些表达条件查询的关键字,大致如下:
- And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(String user, Striang pwd);
- Or --- 等价于 SQL 中的 or 关键字,比如 findByUsernameOrAddress(String user, String addr);
- Between --- 等价于 SQL 中的 between 关键字,比如 findBySalaryBetween(int max, int min);
- LessThan --- 等价于 SQL 中的 "<",比如 findBySalaryLessThan(int max);
- GreaterThan --- 等价于 SQL 中的">",比如 findBySalaryGreaterThan(int min);
- IsNull --- 等价于 SQL 中的 "is null",比如 findByUsernameIsNull();
- IsNotNull --- 等价于 SQL 中的 "is not null",比如 findByUsernameIsNotNull();
- NotNull --- 与 IsNotNull 等价;
- Like --- 等价于 SQL 中的 "like",比如 findByUsernameLike(String user);
- NotLike --- 等价于 SQL 中的 "not like",比如 findByUsernameNotLike(String user);
- OrderBy --- 等价于 SQL 中的 "order by",比如 findByUsernameOrderBySalaryAsc(String user);
- Not --- 等价于 SQL 中的 "! =",比如 findByUsernameNot(String user);
- In --- 等价于 SQL 中的 "in",比如 findByUsernameIn(Collection<String> userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
- NotIn --- 等价于 SQL 中的 "not in",比如 findByUsernameNotIn(Collection<String> userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
2.使用 @Query 创建查询
@Query 注解的使用非常简单,只需在声明的方法上面标注该注解,同时提供一个 JP QL 查询语句即可,如下所示:

public interface UserDao extends Repository<AccountInfo, Long> {
@Query("select a from AccountInfo a where a.accountId = ?1")
public AccountInfo findByAccountId(Long accountId);
@Query("select a from AccountInfo a where a.balance > ?1")
public Page<AccountInfo> findByBalanceGreaterThan(
Integer balance,Pageable pageable);
}

很多开发者在创建 JP QL 时喜欢使用命名参数来代替位置编号,@Query 也对此提供了支持。JP QL 语句中通过": 变量"的格式来指定参数,同时在方法的参数前面使用 @Param 将方法参数与 JP QL 中的命名参数对应,示例如下:

public interface UserDao extends Repository<AccountInfo, Long> {
public AccountInfo save(AccountInfo accountInfo);
@Query("from AccountInfo a where a.accountId = :id")
public AccountInfo findByAccountId(@Param("id")Long accountId);
@Query("from AccountInfo a where a.balance > :balance")
public Page<AccountInfo> findByBalanceGreaterThan(
@Param("balance")Integer balance,Pageable pageable);
}

此外,开发者也可以通过使用 @Query 来执行一个更新操作,为此,我们需要在使用 @Query 的同时,用 @Modifying 来将该操作标识为修改查询,这样框架最终会生成一个更新的操作,而非查询。如下所示:
@Modifying
@Query("update AccountInfo a set a.salary = ?1 where a.salary < ?2")
public int increaseSalary(int after, int before);
3.通过调用 JPA 命名查询语句创建查询
命名查询是 JPA 提供的一种将查询语句从方法体中独立出来,以供多个方法共用的功能。Spring Data JPA 对命名查询也提供了很好的支持。用户只需要按照 JPA 规范在 orm.xml 文件或者在代码中使用 @NamedQuery(或 @NamedNativeQuery)定义好查询语句,唯一要做的就是为该语句命名时,需要满足”DomainClass.methodName()”的命名规则。假设定义了如下接口:
public interface UserDao extends Repository<AccountInfo, Long> {
......
public List<AccountInfo> findTop5();
}
如果希望为 findTop5() 创建命名查询,并与之关联,我们只需要在适当的位置定义命名查询语句,并将其命名为 "AccountInfo.findTop5",框架在创建代理类的过程中,解析到该方法时,优先查找名为 "AccountInfo.findTop5" 的命名查询定义,如果没有找到,则尝试解析方法名,根据方法名字创建查询。
参考 http://www.cnblogs.com/WangJinYang/p/4257383.html
【JPA】表达条件查询的关键字的更多相关文章
- Spring Data JPA 条件查询的关键字
Spring Data JPA 为此提供了一些表达条件查询的关键字,大致如下: And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(Stri ...
- jpa多条件查询重写Specification的toPredicate方法(转)
Spring Data JPA支持JPA2.0的Criteria查询,相应的接口是JpaSpecificationExecutor.Criteria 查询:是一种类型安全和更面向对象的查询 . 这个接 ...
- jpa多条件查询
首先继承JpaSpecificationExecutor<T>接口 需要用到JpaSpecificationExecutor<T>中的Page<T> findAll ...
- springboot jpa 多条件查询(多表)
前几天写的,贴上来. 实体类. package com.syl.demo.daomain; import lombok.Data; import javax.persistence.*; /** * ...
- springboot jpa 多条件查询(单表)
需要实现的功能: 多个搜索输入框:全部不填,则查出所有列表:填了条件,就按条件查找:填的条件个数不定. 方法实现的核心:jpa自带的Specification<T> (目前只需要单表,多表 ...
- Spring Boot Jpa 多条件查询+排序+分页
事情有点多,于是快一个月没写东西了,今天补上上次说的. JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将 ...
- MyBatis框架中的条件查询!关键字exists用法的详细解析
exists用法 exists: 如果括号内子查询语句返回结果不为空,说明where条件成立,就会执行主SQL语句 如果括号内子查询语句返回结果为空,说明where条件不成立,就不会执行主SQL语句 ...
- spring data jpa 组合条件查询封装
/** * 定义一个查询条件容器 * @author lee * * @param <T> */ public class Criteria<T> implements Spe ...
- spring jpa : 多条件查询
https://www.cnblogs.com/Donnnnnn/p/6277872.html 方式一: 第一步:EmpAccNumService package com.payease.scford ...
随机推荐
- C语言结构体的引入
#include <stdio.h> struct student{ int ID; ]; int age; }; int main(){ //赋值: , }; ,.name=}; , , ...
- 关于jQuery源码中(function(window,undefined){//dosomething()})(window)写法解释
一.首先是最常见的闭包 (Closure) 范式自执行函数的写法,这里用匿名函数封装(构造块级作用域),避免了匿名函数内部的代码与外部之间发生冲突(如使用了相同的变量名). (function() { ...
- 关于JSP异常的处理
jsp中错误处理页面-isErrorPage="true" 举例说明:mustBeError.jsp <%@ page contentType="text/html ...
- hackerrank Day15: Linked List
#include <iostream> #include <cstddef> using namespace std; class Node { public: int dat ...
- 项目中 mysql中的内容关于上架时间和下架时间
隐藏左边导航 在mysql中,是存放的10位的时间截,在后台添加时,时间的格式是:'Y-m-d H:i',没有秒的 字段 字段名称 字段类型 是否为空 默认值 备注 publish_up int(11 ...
- 在ASP中限制同一表单被多次提交
本文介绍在ASP应用中防止用户在当前会话期间多次提交同一表单的一个简单方法.它主要由四个子程序组成,在较为简单的应用场合,你只要将这些代码放在包含文件中直接引用即可:对于那些较为复杂的环境,我们在文章 ...
- Apache中关于页面缓存的设置
http://www.cnblogs.com/yyyyy5101/articles/1899350.html Expires.Cache-Control.Last-Modified.ETag是RFC ...
- CStdioFile 写文件
前言: 介绍如何使用 CStdioFile 类去写文件. 完整工程代码,点我下载(请注意工程里面需要包含的 <locale.h>头文件 ) 示例: /// My Add // 获取当前路径 ...
- WPF嵌入百度地图完整实现
无论是做App还是web开发,很多都会用到地图功能,一般都会调用第三方的API实现地图功能!而正如国内的地图API提供方,基本上对Android.IOS和web开发提供了很完整的一套API,但是对于桌 ...
- C# ACM poj1006
中国剩余定理 public static void acm1006(int a, int b, int c, int d) { * ; * ; * ; * * ; ) * z; ) * y; ) * ...