一、自定义方法的规则

Spring Data JPA框架在进行方法名解析时,会先把方法名多余的前缀截取掉,比如find,findBy,read,readBy,get,getBy,然后对剩下的部分进行解析。
假如创建如下的查询:findByUserDepUuid(),框架在解析该方法时,首先剔除findBy,然后对剩下的属性进行解析,假设查询实体为Doc
1:先判断userDepUuid(根据POJO规范,首字母变为小写)是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,继续第二步;
2:从右往左截取第一个大写字母开头的字符串此处为UUID),然后检查剩下的字符串是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设用户为查询实体的一个属性;
3:接着处理剩下部分(DepUuid),先判断用户所对应的类型是否有depUuid属性,如果有,则表示该方法最终是根据“Doc.user.depUuid”的取值进行查询;否则继续按照步骤2的规则从右往左截取,最终表示根据“Doc.user.dep.uuid”的值进行查询。
4:可能会存在一种特殊情况,比如Doc包含一个用户的属性,也有一个userDep属性,此时会存在混合。可以明确在属性之间加上“_”以显式表达意思,比如“findByUser_DepUuid )“或者”findByUserDep_uuid()"
关键词    样品    JPQL片段
IsNotNull findByAgeNotNull ...其中x.age 不为空【年龄不为空】
喜欢 findByNameLike ...其中x.name是什么样的?【模糊查找是......】
不喜欢 findByNameNotLike ...其中x.name不喜欢?【模糊查找不是......】
从...开始 findByNameStartingWith ...其中x.name类似?(参数绑定附加%)【模糊匹配,类似使用%结尾】
EndingWith findByNameEndingWith ...其中x.name类似于?(参数与预置%绑定)【模糊匹配,类似使用%开始】
含 findByNameContaining ...其中x.name like?(参数绑定在%中)[模糊匹配,类似使用%开头和结尾]
排序依据 findByAgeOrderByName ...其中x.age =?order by x.name desc 【查找后排序】
不 findByNameNot ...其中x.name <>?【查找列不是...的】
在 findByAgeIn ...哪里x.age在?
NotIn findByAgeNotIn ...其中x.age不在?
真正 findByActiveTrue ...其中x.avtive = true
产品嫁接 findByActiveFalse ...其中x.active = false
和 findByNameAndAge ...其中x.name =?和x.age =?2
要么 findByNameOrAge ...其中x.name =?或x.age =?2
之间 findBtAgeBetween ...其中x.age之间?和?2
少于 findByAgeLessThan ...其中x.age <?
比...更棒 findByAgeGreaterThan ...其中x.age>?
在那之后 ... ...
一片空白 findByAgeIsNull ...其中x.age为空

自定义查找实例:

    /**
* 根据id查用户
**/
List<User> findByIdOrName(Long id,String name); /**
* 根据id查用户
**/
User queryXXXXByName(String name); /**
* 根据id查name
**/
User readNameById(Long id); /**
* 查年龄为10岁的学生
**/
List<User> getByAge(int age);

三,Spring Data JPA分页查询:

    /**
* 分页查询左右用户
* @param pageable
* @return
*/
Page<User> findAll(Pageable pageable); /**
* 分页查询id不是传入id的用户
* @param id
* @param pageable
* @return
*/
Page<User> findByIdNot(Long id,Pageable pageable);

【注意】分页查询,的结果页,,页接口继承自切片,这个接口有以下方法

public interface Slice<T> extends Iterable<T> {
int getNumber();//返回当前页码 int getSize();//返回当前页大小(可能不是一整页) int getNumberOfElements();//返回当前的元素数量 List<T> getContent();//返回当前页的内容(查询结果) boolean hasContent();//判断是否有内容存在 Sort getSort();//返回排序方式 boolean isFirst();//判断是不是第一页 boolean isLast();//判断是不是最后一页 boolean hasNext();//判断是否还有下一页 boolean hasPrevious();//判断是否上一页 Pageable nextPageable();//返回下一页 Pageable previousPageable();//返回上一页,如果当前已经是第一个,则返回,请求前一个可以是【null】。在调用此方法之前,客户端应该检查是否收到一个非值。 <S> Slice<S> map(Converter<? super T, ? extends S> var1);//用给定的映射,映射当前的内容,为Slice
}
方法名    关键字    SQL
findById 其中id =?
findByIdIs 是 其中id =?
findByIdEquals 等于 其中id =?
findByNameAndAge 和 where name =?和年龄=?
findByNameOrAge 要么 where name =?或年龄=?
findByNameOrderByAgeDesc 按顺序排列 where name =?按年龄顺序排列
findByAgeNotIn 不在 年龄不在(?)
findByStatusTrue 真正 where status = true
findByStatusFalse 假 其中status = false
findByAgeBetween 之间 年龄在哪?和?
findByNameNot 不 名称<>?
findByAgeLessThan 少于 年龄<?
findByAgeLessThanEqual LessThanEqual 年龄<=?
findByAgeGreaterThan 比...更棒 年龄>?
findByAgeGreaterThanEqual GreaterThanEqual 年龄> =?
findByAgeAfter 后 年龄>?
findByAgeBefore 之前 年龄<?
findByNameIsNull 一片空白 其中名称为空
findByNameNotNull 不为空 其中名称不为空
findByNameLike 喜欢 哪里的名字像?
findByNameNotLike 不喜欢 哪里的名字不像?
findByNameStartingWith 从...开始 名称如'?%'
findByNameEndingWith EndingWith 名称如'%?'
findByNameContaining 含 名称如'%?%'

代码中几个复杂的。 
findByNameAndAgeAndSex:表示where name =?和年龄=?和性=? 
findByNameInAndAgeIsNull:表示(?)中的名称和年龄为null  
findByNameAndAgeInAndSexIn:表示where name =?年龄(?)和性别(?)

可以看出关键字是可以连用的,查找都是用findBy +表中列名,表的列名还有关键字等等拼接时,它们的首字母要大写。

二、懒加载引起的no-session解决方法之一,没有页面只有测试用例没有效果

  懒加载造成JPA提供的findOne方法和save 方法在关联表查询和保存时报错;所以适合单表操作,多表可以通过自定义方法分别执行

   保存和更新需要通过@Query的方法执行

三、@Query注解的使用

1. 一个使用@Query注解的简单例子

@Query(value = "select name,author,price from Book b where b.price>?1 and b.price<?2")
List<Book> findByPriceRange(long price1, long price2);

2.  Like表达式

@Query(value = "select name,author,price from Book b where b.name like %:name%")
List<Book> findByNameMatch(@Param("name") String name);

3. 使用Native SQL Query

所谓本地查询,就是使用原生的sql语句(根据数据库的不同,在sql的语法或结构方面可能有所区别)进行查询数据库的操作。

@Query(value = "select * from book b where b.name=?1", nativeQuery = true)
List<Book> findByName(String name);

4. 使用@Param注解注入参数

@Query(value = "select name,author,price from Book b where b.name = :name AND b.author=:author AND b.price=:price")
List<Book> findByNamedParam(@Param("name") String name, @Param("author") String author,
@Param("price") long price);

5. SPEL表达式(使用时请参考最后的补充说明)

'#{#entityName}'值为'Book'对象对应的数据表名称(book)。

public interface BookQueryRepositoryExample extends Repository<Book, Long>{

@Query(value = "select * from #{#entityName} b where b.name=?1", nativeQuery = true)
       List<Book> findByName(String name);

}

6. 一个较完整的例子

public interface BookQueryRepositoryExample extends Repository<Book, Long> {
@Query(value = "select * from Book b where b.name=?1", nativeQuery = true)
List<Book> findByName(String name);// 此方法sql将会报错(java.lang.IllegalArgumentException),看出原因了吗,若没看出来,请看下一个例子 @Query(value = "select name,author,price from Book b where b.price>?1 and b.price<?2")
List<Book> findByPriceRange(long price1, long price2); @Query(value = "select name,author,price from Book b where b.name like %:name%")
List<Book> findByNameMatch(@Param("name") String name); @Query(value = "select name,author,price from Book b where b.name = :name AND b.author=:author AND b.price=:price")
List<Book> findByNamedParam(@Param("name") String name, @Param("author") String author,
@Param("price") long price); }

7.  解释例6中错误的原因:

因为指定了nativeQuery = true,即使用原生的sql语句查询;否则表名需为实体类对象。使用java对象'Book'作为表名来查自然是不对的。只需将Book替换为表名book。

@Query(value = "select * from book b where b.name=?1", nativeQuery = true)
List<Book> findByName(String name);
@Param入参有此注解,则sql中用:name接收参数;否则用?1的占位符接收参数且顺序也要一致

8.   有同学提出来了,例子5中用'#{#entityName}'为啥取不到值啊?

  先来说一说'#{#entityName}'到底是个啥。从字面来看,'#{#entityName}'不就是实体类的名称么,对,他就是。

  实体类Book,使用@Entity注解后,spring会将实体类Book纳入管理。默认'#{#entityName}'的值就是'Book'。

  但是如果使用了@Entity(name = "book")来注解实体类Book,此时'#{#entityName}'的值就变成了'book'。

  只需要在用@Entity来注解实体类时指定name为此实体类对应的表名。在原生sql语句中,就可以把'#{#entityName}'来作为数据表名使用。

9.  @Modifying注解

    1、在@Query注解中编写JPQL实现DELETE和UPDATE操作的时候必须加上@modifying注解,以通知Spring Data 这是一个DELETE或UPDATE操作。

    2、UPDATE或者DELETE操作需要使用事务,此时需要 定义Service层,在Service层的方法上添加事务操作。  

spring-data-JPA repository自定义方法规则的更多相关文章

  1. spring data jpa方法命名规则

    关键字 方法命名 sql where字句 And findByNameAndPwd where name= ? and pwd =? Or findByNameOrSex where name= ? ...

  2. spring data jpa 使用方法命名规则查询

    按照Spring Data JPA 定义的规则,查询方法以findBy开头,涉及条件查询时,条件的属性用条件关键字连接,要注意的是:条件属性首字母需大写.框架在进行方法名解析时,会先把方法名多余的前缀 ...

  3. Spring Data JPA教程, 第八部分:Adding Functionality to a Repository (未翻译)

    The previous part of my tutorial described how you can paginate query results with Spring Data JPA. ...

  4. 快速搭建springmvc+spring data jpa工程

    一.前言 这里简单讲述一下如何快速使用springmvc和spring data jpa搭建后台开发工程,并提供了一个简单的demo作为参考. 二.创建maven工程 http://www.cnblo ...

  5. 【Spring】Spring Data JPA

    原始JDBC操作数据库 传统JDBC方式实现数据库操作 package com.imooc.util; import java.io.InputStream; import java.sql.*; i ...

  6. spring data jpa(一)

    第1章     Spring Data JPA的快速入门 1.1   需求说明 Spring Data JPA完成客户的基本CRUD操作 1.2   搭建Spring Data JPA的开发环境 1. ...

  7. Spring Data Jpa的四种查询方式

    一.调用接口的方式 1.基本介绍 通过调用接口里的方法查询,需要我们自定义的接口继承Spring Data Jpa规定的接口 public interface UserDao extends JpaR ...

  8. 12 Spring Data JPA:springDataJpa的运行原理以及基本操作(下)

    spring data jpaday1:orm思想和hibernate以及jpa的概述和jpa的基本操作 day2:springdatajpa的运行原理 day2:springdatajpa的基本操作 ...

  9. 黑马程序员spring data jpa 2019年第一版本

    第一步首先创建一个maven工程,导入对于的pom依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xs ...

  10. Spring Data JPA进阶——Specifications和Querydsl

    Spring Data JPA进阶--Specifications和Querydsl 本篇介绍一下spring Data JPA中能为数据访问程序的开发带来更多便利的特性,我们知道,Spring Da ...

随机推荐

  1. NX二次开发-UFUN将实体放入STL文件中函数UF_STD_put_solid_in_stl_file

    NX9+VS2012 #include <uf.h> #include <uf_obj.h> #include <uf_modl.h> #include <u ...

  2. NX二次开发-UFUN关闭STL文件函数UF_STD_close_stl_file

    NX9+VS2012 #include <uf.h> #include <uf_obj.h> #include <uf_modl.h> #include <u ...

  3. NX二次开发-UFUN查询对象的类型和子类型UF_OBJ_ask_type_and_subtype

    NX9+VS2012 #include <uf.h> #include <uf_obj.h> #include <uf_modl.h> #include <u ...

  4. NX二次开发-算法篇-冒泡排序(例子:遍历所有点并排序)

    NX9+VS2012 #include <uf.h> #include <uf_ui.h> #include <uf_curve.h> #include <u ...

  5. CSS3:教程

    ylbtech-CSS3:教程 1.返回顶部 1. CSS3 教程 CSS 用于控制网页的样式和布局. CSS3 是最新的 CSS 标准. 本教程向您讲解 CSS3 中的新特性. 开始学习 CSS3! ...

  6. java时间工具类,时间相互转换

    /* * @author XueWeiWei * @date 2019/8/26 16:22 */ package com.nps.utils; import java.text.ParseExcep ...

  7. spring boot 重复提交

    package com.future.interceptor; import javax.servlet.http.HttpServletRequest; import org.aspectj.lan ...

  8. C++之运算符_算数运算符

    运算符 **作用:**用于执行代码的运算 | **运算符类型** | **作用** || -------------- | -------------------------------------- ...

  9. Mybatis与Spring整合(CURD)

    项目采用Maven构建,用Junit进行测试,数据库是Mysql,连接池是c3p0,未测试缓存部分 1.Maven的“pom.xml”文件 <project xmlns="http:/ ...

  10. 【JZOJ4665】数列

    description analysis 水法又\(n\)方二十万-- 可以先离散化,然后枚举起点,枚举向下扫 同一个数出现过或模数不相同就\(break\),注意\(k\)不够顶替还是有可能存在解不 ...