Spring Data JPA使用必备(二):Spring Data JPA方法命名规则实现SQL自动生成

Spring data JPA是一个好东西,但是对于很多习惯于写SQL,直接怼数据库的人来说,这个真的用不习惯,还被一致认为是一个不易于程序员发展的技术。因为JPA提供了标准的封装,在操作数据库的时候,不需要写SQL,完全通过操作对象即可完成。久而久之,SQL就会被慢慢的遗忘,生疏,等以后面试的时候,也许这就是上升的一个短板。现在各大公司对JPA用的都很少,除非是这个公司的系统涉及到几种数据库,随时有可能出现数据库之间的迁移,为了SQL的兼容性使用JPA。这也是JPA的一个最大优点,不是之一。至少我是这么认为的。在这篇博文里面,我们就来聊聊,不要通过写任何SQL来实现对数据库的基本操作。

核心Repository

Spring Data库的核心接口是Repository,使用domain类去管理,domain类中的id类型作为类型参数,这个接口主要作为一个标记接口,依靠具体的类型运作并帮助发现接口。其直接集成接口为CrudRepository,提供了丰富的CRUD功能去管理实体类。

然后就是用于分页排序的PagingAndSortRepository接口类,它继承于CrudRepository接口。提供了丰富的分页和排序的功能API。说丰富其实就两个功能,不过对付基本的排序功能还是能够完成使用的。

最后就是JpaRepository,这个类中也有封装基本的方法。这个类是继承了PagingAndSortRepository接口,同时也继承了QueryByExampleExecutor执行器接口。

继承图关系如下:

JPA的上手使用

JPA的依赖

这里只基于整合Spring boot方式的JPA依赖引入,如果使用Spring MVC的可以到网上找一下需要哪些依赖。


    org.springframework.boot
    spring-boot-starter-data-jpa

JPA的配置

不管是JPA还是Mybatis都是需要提前完成一些配置,对于JPA来说比较简单,进行一下配置即可。

在基于Spring boot的配置:

@EnableJpaRepositories
public class JpaConfig{}

主要是这个注解,一般是放在XxxxApplication启动类上。

在基于非Spring boot的项目配置,可以用XML来实现:



    

这里基于XML配置的方式,实话说我是没有用过的,不过大概可以看的出来类似于配置Spring的@ComponentScan配置类扫描的基础路径。在@EnableJpaRepositories中也是有basePackages属性的。

之所以这里基于XML方式的配置不多说,是因为现在着手开发的项目都是基于Spring boot,另外Spring boot是将来发展的一个趋势,不,不是将来,现在就有绝大部分项目(新启动的项目)都会使用Spring boot。所以基于XML方式的,用到才具体研究吧,上面的配置是摘抄于Spring data JPA官方文档。

另外还有一些JPA的配置信息和数据库的配置信息在第一篇文章里面有体现,这里不赘述。

创建Entity实体类

通过Entity实体类指定对应的数据表,和表的字段形成映射关系。简单的写法如下:

@Entity
@Table(name = "t_user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;
    @Column(name = "user_name")
    private String userName;
    @Column(name = "phone")
    private String phone;
    @Column(name = "age")
    private Integer age;
}

这种提供注解的方式指定数据表和表字段的映射关系,在本系列的第一篇文章说过了,这里就不详细说拉。

创建Repository接口

这里在创建对应的UserRepository接口类的时候必须继承Repository接口或者其子类接口。这个需要看需求,如果不需要使用本身提供的CRUD方法、分页、排序等功能的话,直接继承Repository接口即可。但是对于正常来说,原生提供的API多少是会用上一点的,即使用不上,自己拥有也不是一件坏事,所以在项目开发中都是直接继承JpaRepository接口。在泛型里面执行对应的实体类Entity和主键的类型。这两个参数很重要,不可少。

public interface UserRepository extends JpaRepository{
    //……
}

到这里整个JPA的信息都构建结束,需要使用什么操作,就在UserRepository接口里面加入相应的方法即可。

基于方法的骚操作

这部分内容是这篇文章的重点,就是通过不同方法名的组合来实现SQL自动的生成,不需要自己写一行SQL代码。接下来说几种常用的情况来引入一下。

find…By…

在查询语句的时候,可能会不带条件,可能会带条件,这里在看看find…By…的基本用法。

User findById(Long id);//1
List findTop10ByAge(Integer age);//2
User findByUserNameAndPhone(String userName,String phone);//3

通过上面的3个方法可以大体了解一下find…By…的用法。

  • 第一句表示按照id查询。
  • 第二句是根据年龄查询数据,然后筛选出前十条数据作为结果返回,注意这里的排序规则是默认的ASC,按照id排序,如果需要指定具体的排序规则,可以通过OrderBy实现。
  • 第三句是通过条件查询,多个条件字段用And连接,当然不仅限于And,Or也是可以的,根据实际的需要来即可。

这三句已经大概可以了解find…By…的使用,当然这里可以使用的情况很多。可以通过debug日志看具体生成的SQL语句是什么样的,这里就不去展示了。

注意:这里的参数匹配是通过参数的位置来自动匹配的,如By后面有三个条件,那么对应的就是三个参数,且按照顺序匹配,不需要使用@Param注解指定参数的名称。(具体可看最后总结的分析)

OrderBy

排序在查询的时候经常会用到,使用起来也不是很难,可以支持多个字段的排序,并指定正序和倒序排列。

List findAllOrderByAgeDescAndIdAsc();

通过这一个方法就可以了解OrderBy的写法,首先指定按照age倒序排序,如果age相同使用id正序排序。这个不难理解,多个条件会写,单个条件也不在话下了。

Like、NotLike、StartingWith、EndingWith和Containing

模糊查询,肯定会用到的,直接看实现的代码示例:

List findByUserNameLike(String userName);//1
List findByUserNameNotLike(String userName);//2
List findByUserNameStartingWith(String userName);//3
List findByUserNameEndingWith(String userName);//4
List findByUserNameContaining(String userName);//5
  • 1:表示按照userName字段模糊查询,会自动加上like关键字,但是不会在userName对应的值上面添加%或者_,需要在传入值的时候,手动将占位符和实际值组装起来;
  • 2:会自动加上not like关键字,占位符需要自己手动添加;
  • 3:自动加上like关键字,这里不需要手动添加占位符,会自动在字段值的前面加上%,转换后:like '%Joker'
  • 4:和第三句差不多,差别就是占位符%放置的位置调整,放在了字段值的后面;
  • 5:相当于第三句和第四句的综合,会在字段值的前后加上占位符%
下面的列表喜欢吗

上面随机列举了几个经常使用用的查询方式,实际上还是有很多的,另外除了find开头的方式,还可以用get开头。看下面面的列表:

关键字 方法命名 sql where字句
And findByNameAndPwd where name = ? and pwd= ?
Or findByNameOrSex where name = ? or sex =?
Between findByIdBetween where id between ? and ?
LessThan findByIdLessThan where id
LessThanEqual findByIdLessThanEqual where id <=?
GreaterThan findByIdGreaterThan where id > ?
GreaterThanEqual findByIdGreaterThanEqual where id >= ?
After findByIdAfter where id > ?
Before find ByIdBefore where id < ?
IsNull findByNameIsNull where name is null
IsNotNull,NotNull findByNameIsNotNull
findByNameNotNull
where name is not null
Like findByNameLike where name like ?
NotLike findByNameNotLike where name not like ?
StartingWith findByNameStartingWith where name like '?%'
EndingWith findByNameEndingWith where name like '%?'
Containing findByNameContaining where name like '%?%'
OrderBy findByIdOrderByAgeDescAndIdAsc where id = ? order by age desc,id asc
Not findByNameNot where name <> ?
In findByNameIn where name in (?)
NotIn findByIdNotIn where id not in (?)
True findByDelStatusTrue where delStatus = true
False findByDelStatusFalse where delStatus = false
IgnoreCase findByNameIgnoreCase where UPPER(name) = UPPER(?)

get开头的方法就不单独写了,如果习惯使用get开头,替换掉find即可。

看到这里就知道,这些自动生成的SQL都是只支持查询,且是单表、非复杂SQL语句的实现。如果涉及到条件太多,很可能一个方法名能够占一行。

总结

整个JPA的基于方法名使用就这么多了,至于怎么取融汇贯通就看自己的造诣了。其实并不难。下面以一个例子结束这篇博客。

示例代码:

SQL语句
select * 
from t_user 
where 
user_name like '%er' 
and id >=100 
and (age between 20 and 35)  
order by age DESC,id ASC
方法定义
List findByUserNameLikeAndIdGreaterThanEqualAndAgeBetweenOrderByAgeDescAndIdAsc(String userName,Long id,Integer startAge,Integer endAge);

说明:userName、id分别匹配前面两个参数,由于age是between范围查询,是在两个值之间,需要对应到两个参数。所以做种的参数是四个,且位置要按照顺序传入,不能错位。

方法名是不是巨长、巨牛,想要更长,就看你的脑洞啦!

本文作者:程序猿杨鲍
版权归作者所有,转载请注明出处

你可能感兴趣的:(Spring Data JPA使用必备(二):Spring Data JPA方法命名规则实现SQL自动生成)