微人事第五天:Spring Data Jpa关键字定义查询方法
虽然Jpa中有定义好的方法,但是还不够我们使用,我需要在接口中自己定义一些方法。
1.BookDao
这里定义一个根据id查询Book
package org.javaboy.jpa.dao;
import org.javaboy.jpa.bean.Book;
import org.springframework.data.jpa.repository.JpaRepository;
//操作实体类Book
//继承接口,第一个泛型是你要操控的实体类,第二个反应是id的属性
public interface BookDao extends JpaRepository<Book,Integer> {
Book findBookById(Integer id);
}
2.测试类
查询id=3的书
@Test
public void find4() {
Book book = bookDao.findBookById(3);
System.out.println(book);
}
控制打印sql语句和查询结果
Hibernate: select book0_.id as id1_0_, book0_.author as author2_0_, book0_.name as name3_0_ from book book0_ where book0_.id=?
Book{id=3, name='西游记', author='吴承恩'}
dao层中我们可以按住规则来定义满足要求的方法.
支持的查询关键字如下图所示:
下面更具表格我们再来定义一些查询方法:
分别是查询大于id的数据和查询小于id的数据或者对名称模糊查询。
List<Book> findByIdGreaterThan(Integer id);
List<Book> findBookByIdLessThanOrNameContaining(Integer id,String name);
测试类:
@Test
public void find5() {
List<Book> list = bookDao.findByIdGreaterThan(3);
System.out.println(list);
List<Book> list1 = bookDao.findBookByIdLessThanOrNameContaining(3, "楼");
System.out.println(list1);
}
可以看到查询成功了,查询的sql语句和查询结果都被打印出来。
[Book{id=4, name='红楼梦', author='曹雪芹'}]
Hibernate: select book0_.id as id1_0_, book0_.author as author2_0_, book0_.name as name3_0_ from book book0_ where book0_.id<? or book0_.name like ? escape ?
[Book{id=1, name='三国演义', author='罗贯中'}, Book{id=2, name='水浒传', author='施耐庵'}, Book{id=4, name='红楼梦', author='曹雪芹'}]
查询方法流程解析:
为什么写上方法名,JPA就知道你想干嘛了呢?假如创建如下的查询:findByUserDepUuid(),框架在解析该方法时,首先剔除 findBy,然后对剩下的属性进行解析,假设查询实体为Doc:
1.先判断 userDepUuid (根据 POJO 规范,首字母变为小写)是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,继续第二步;
2.从右往左截取第一个大写字母开头的字符串(此处为Uuid),然后检查剩下的字符串是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设 user 为查询实体的一个属性;
3.接着处理剩下部分(DepUuid),先判断 user 所对应的类型是否有depUuid属性,如果有,则表示该方法最终是根据 “ Doc.user.depUuid” 的取值进行查询;否则继续按照步骤 2 的规则从右往左截取,最终表示根据 “Doc.user.dep.uuid” 的值进行查询。
4.可能会存在一种特殊情况,比如 Doc包含一个 user 的属性,也有一个 userDep 属性,此时会存在混淆。可以明确在属性之间加上 “_” 以显式表达意图,比如 “findByUser_DepUuid()” 或者 “findByUserDep_uuid()”
5.还有一些特殊的参数:例如分页或排序的参数: