总感觉很少用到SpringDataJpa。没想到最近有好几个朋友问Jpa的问题。思前想后,我把自己所了解的关于Jpa的一些知识点,整理写了几篇文章分享给大家,今天就简单的看一篇吧。大家都知道SpringDataJpa有一个“神奇”的功能,就是我们只需要按照既定的规则定义方法名即可,不需要自己写SQL。至于具体的实现原理,松哥2019年的文章中已经介绍过,这里不再赘述(公众号后台回复2019有当年的文章索引)。今天想和大家聊一聊SpringDataJpa支持的方法前缀。在我们日常开发中,如果用到SpringDataJpa,用的最多的就是findXXX。有些人可能会使用getXXX或readXXX。我认为这些是最常用的。其实SpringDataJpa支持的方法前缀多达11种,我们来看一下:相关源码在org.springframework.data.repository.query.parser.PartTree类中:privatestaticfinalStringQUERY_PATTERN="find|read|get|query|search|stream";privatestaticfinalStringCOUNT_PATTERN="count";privatestaticfinalStringEXISTS_PATTERN="exists";privatestaticfinalStringDELETE_PATTERN="delete|remove";下面宋哥就举几个例子,大家一起过一下吧。如果你没有用过SpringDataJpa,可以在公众号后台回复666。宋兄在之前的SpringBoot教程中有介绍过,大家可以先学习一下,不然这篇文章学起来可能有点迷糊。没脑子。1.查询我们先来看查询。find/get/read/query/search都是正则前缀,我们来看几个例子:publicinterfaceUserRepositoryextendsJpaRepository{/***通过用户名查询用户*@paramusername*@return*/UserfindUserByUsername(字符串用户名);/***根据用户地址查询用户*@paramaddress*@return*/ListgetUserByAddress(Stringaddress);/***查询某个日期之后出生的用户*@parambirthday*@return*/ListreadUserByBirthdayAfter(LocalDatebirthday);/***查询某个日期之前出生的用户*@parambirthday*@return*/ListqueryUserByBirthdayBefore(LocalDatebirthday);/***根据性别查询用户*@paramgender*@return*/ListsearchUserByGender(Stringgender);}每个方法的意思我都注释了,这里就不赘述了。需要注意的是,在IDEA中写的时候,前四个是有提示的,但是最后一个搜索是没有提示的,朋友自己写也没有提示,所以不要写错了。.除了上面五个常规的,还有一个有点特殊的,就是stream,其实也没什么特别的。毕竟Java的版本每年都在变化。JDK8快十年了,stream应该已经掌握了(还不了解stream的朋友,可以在公众号后台回复2021,有松哥去年的文章索引,介绍过stream在去年的WebFlux系列中有详细介绍)。我们来看一个流的例子:publicinterfaceUserRepositoryextendsJpaRepository{/***根据地址查询用户,返回流stream*@paramaddress*@return*/StreamfindUserByAddress(Stringaddress);}返回值只是一个流。这里有一点需要注意,就是在调用返回值为stream的方法时,需要添加一个事务。如果不添加事务,会报如下错误:org.springframework.dao.InvalidDataAccessApiUsageException:You'retryingtoexecuteastreamingquerymethodwithoutasurroundingtransactionthatkeepstheconnectionopensothatStreamcanactuallybe消费。确保使用流的代码使用@Transactional或任何其他声明(只读)事务的方式。这个错误的意思很明确,就是你要将流查询放到一个事务中,保证流操作不会关闭数据库连接。因为流中没有保存数据,所以如果Connection关闭,就无法操作数据。宋哥给大家展示一个简单的流方法调用案例:@AutowiredUserRepositoryuserRepository;@Test@Transactional(readOnly=true)voidtest01(){Listlist=userRepository.findUserByAddress("Shenzhen").map(u->{u.setAddress("China"+u.getAddress());returnu;}).collect(Collectors.toList());System.out.println("list="+list);}从数据库中查询到数据后,在所有地址中加上“China”字样。2.统计count关键字可以用来统计。我们看下面的例子:publicinterfaceUserRepositoryextendsJpaRepository{/***统计某个地址有多少用户*@paramaddress*@return*/LongcountByAddress(Stringaddress);/***去重统计某个地址有多少用户*@paramaddress*@return*/LongcountDistinctByAddress(Stringaddress);}统计两个例子,第二个是去重后。3.判断存在可以用来做判断。我们看一个例子:publicinterfaceUserRepositoryextendsJpaRepository{/***判断某个地址是否存在用户*@paramaddress*@return*/BooleanexistsUserByAddress(Stringaddress);}4.删除即可使用delete或remove关键字删除。我们来看两个例子:publicinterfaceUserRepositoryextendsJpaRepository{/***根据地址删除用户*@paramaddress*@return*/IntegerdeleteUserByAddress(Stringaddress);/***根据地址删除用户*@paramaddress*@return*/IntegerremoveUserByAddress(Stringaddress);}需要注意的是,在事务中也会调用delete方法。5.总结好了,这就是松哥给大家介绍的SpringDataJpa中数据库操作方法默认的10个前缀。当然,如果这些前缀不能满足操作,那么可以加上@Query注解,这个是另外一个话题了,后面再说。