概述
Spring Data作为Spring生态系统的持久层访问框架,如今基本涵盖了大量SQL,NOSQL数据库的集成,而作为访问关系型数据库的技术Spring Data JPA也是可以非常轻松的直接使用。注解以及Repository接口的自动生成实现,单表操作几乎不用写逻辑代码。同时IDEA的JPA Buddy插件也非常好的支持了这些功能。
一、启用插件
如图JPA Bubby,下载并启用该插件,可以让Spring Data JPA在IDEA中的使用更加强大、方便、快速。注意,该插件需要付费使用,但也有免费版本,基本功能足矣。
本文使用的IDEA版本为2023.2的最新版本,JPA Bubby插件也是最新版本的插件,不同版本可能与本文中提到的不符,因此请注意。
二、生成实体类
在项目窗口右键或者快捷键Alt+insert,可以看到JPA Entity和JPA Entities from DB选项: 在JPA Entities from DB选项中,可以选择根据已存在的表创建实体类Entity,前提是先用IDEA的Database工具连接上你的数据库。 DB connection选择你IDEA连接到的数据库,在Tables选项中选择对应的数据库表,Class name填写你想对应的表生成的实体类名,然后就是该类放置的包,最后点击OK,就会自动生成表对应的实体类。
三、生成DTO类
在项目窗口右键或者快捷键Alt+insert,可以看到DTO选项: 选择DTO后弹出以下窗口: Package写成你想放置DTO类的包,Domain entity选择DTO对应的实体类,然后就是DTO类的类名。
下面会让你选择实体类的哪些字段会生成到DTO中,这个看个人需要选择即可。那些默认选中的勾会生成标准Java 类对应的方法,通常不需要更改,默认即可。如果项目中添加了Lombok依赖,则会使用Lombok注解代替方法。最后点击OK,对应的DTO类也就自动生成。
四、生成Repository接口
在项目窗口右键或者快捷键Alt+insert,可以看到Spring Data JPA Repository选项: 选择Spring Data JPA Repository后弹出以下窗口: 这里的选项也是见名知意,Entity对应Repository接口的实体类,Name为Repository接口的名称,Parent选择你这个Repository接口继承的Spring Data原生的Repository接口,通常是JpaRepository、CrudRepository、或者用于分页和排序的PagingAndSortingRepository之一。最后选择放置Repository接口的包,点击OK。
五、自动生成Repository接口的数据访问API
将光标放在实体类的某个属性上(比如age),使用快捷键Alt+enter,弹出下图所示的悬浮框: 选择其中的Create Spring Data repository method,然后继续弹出以下悬浮框: 这些选项中以Method开头的都是简单的方法,而以Query开头的选项会在生成的Repository方法上加上@Query注解,注解包含对应的JPA查询语句(也叫做JPQL),使用过JPA的小伙伴应该都知道。在这里,我先以Method Find Collection和Query Find Collection为例,看看这两种方式生成的方法的差异。其余的都是对应基本的增删改查,很好理解,触类旁通就行。Find Instance和Find Collection的区别是:前者的返回值是一个单一实体;后者返回值是一个包含多个实体的集合。接下来我先选择Method Find Collection,如图: 在上面:
- 标记1选择方法返回的集合类型,通常为List、Set、Collection,也可以是Stream、Flux等。
- 标记2选择方法返回的实体类型。
- 标记3选择根据哪个字段进行查询,通常我们像之前所说的将光标放在属性上操作的话,这里的属性默认就是我们选择的属性。
- 标记4选择查询的条件,这些都对应基本的SQL查询的条件,例如比较查询、区间、是否是、以及是否为空、模糊查询等。
- 标记5表示是否忽略数据库字段的大小写。
- 标记6表示是否为null,如果选择NonNull表示不会将该字段为null的记录查询出来。
- 标记7就是一些更高级的选项,分别表示去重、排序、分页、以及方法的前缀。Async表示会将方法的返回值封装成一个Future或CompleteFuture的异步对象。
- 标记8处可以选择根据哪个字段进行排序,点击Add order by attribute,选择对应的属性以及排序的方式,如图:
有时候,我们可能也会根据多个字段进行and和or查询,就可以像下图所示,添加额外的字段及条件: 首先点击标记1处的+号,然后标记2处选择and还是or。Attribute选择对应的字段,后面的操作跟之前也是一样,可以选择适当的查询条件,如果有更多的话也可以再添加对应的属性。
最后,我选择以下的配置: 这会生成一个方法,用于查询名字以给定参数字符串忽略大小写结尾,并且age小于给定的参数。两者都不能为null,然后根据age降序排序,并分页。最终生成的方法如下: 可以看到生成的方法名也是很好理解,同时也是遵循Spring Data Repository接口方法的命名约定。
第一和第二个参数对应之前配置的两个查询条件的参数,例如,如果想查询名称以“m”结尾以及年龄小于25的所有记录,就可以在调用该方法时,传入25和“m”两个参数。第三个参数为Pageable,表示一个分页的操作,通常可以使用PageRequest类的静态方法PageRequest.of(int page,int size)实现,其中page表示第几页,size表示一页的大小。
此外也可以使用对应的SQL语句来实现上述查询的作用,也就是前面所说的创建Repository Method时选择Query Find Collection: 之后的操作跟之前一样,如图: 最后点击OK,生成的方法如下: 两种方式的作用都是一样的,只不过第二种是使用JPA的查询语言,具体有什么差异可以搜索有关这两种的细微差距。
六、表之间一对一,一对多,多对多的映射关系
在JPA中将表之间的映射关系,反映到实体间的映射关系。这是通过@OneToMany、@ManyToOne、@OneToOne、@JoinColume、@ManyToMany、@JoinTable几个注解来反映这种映射关系的。如果你熟练的理解表之间的映射关系,可以更好、更迅速的通过IDEA自动的生成注解来反映这种表的映射关系,从而无需在手动地添加复杂的JPA注解。
首先看一对一映射,以下例子只是演示,实际表之间的映射关系由自己确认。
假设我们有一个Person类,以及与之一对一的Car类。在这里,Person类已经存在我们的项目中,由于某种需求需要另一个Car类与之映射,如下图Person实体类,包含简单的id及name属性: 现在我们就可以通过IDEA自动生成一个与之一对一的Car类。将鼠标光标放在Person类类名上,按住Alt+enter,弹出以下悬浮框,选择Create Referenced Entity: Name和Package填写对应映射实体的类名,包名(通常都是默认选好)。Parent选项可以不需要选择,在Referenced type选项中选择对应的映射关系:一对一、多对一、一对多、多对多,这里选择ONE_TO_ONE,然后选择主键ID的数据类型及生成策略,如下图所示: 最后点击OK,就会自动生成Car类以及配置对应的映射关系:
可以看到,Person类中添加了对应的Car属性以及相应的注解,同时也生成了Getter和Setter方法(使用Lombok注解)。如果Car类需要额外的属性,只需自行添加即可。
将鼠标光标放在Person类上选择快捷键Alt+enter,在弹出的悬浮框中选择Show Entity Relationship Diagram,可以查看实体类之间的映射关系图: 以下为Person实体与Car实体之间的对应关系,确实反映出一对一的关系: 同理,假设Teacher实体类与Book实体类存在一对多的关系,也可以快速实现。跟前面步骤一样,将光标放在Teacher类名上,按住快捷键Alt+enter,或者也可以右键点击左侧的图标,也可以弹出该悬浮框,如图: 然后还是选择Create Referenced Entity,填写相应的选项,选择ONE_TO_MANY的映射关系,如图: 点击OK后也会生成相应的Book实体类,以及配置相应的映射关系:
多对多的映射关系也是同理,只要自己知道表之间、实体之间的关系,都可以轻松地自动生成。
七、相关工具窗口的简单介绍
最后介绍一些可能有用的工具窗口。当我们右键点击实体类名左边的图标后,会弹出以下悬浮框: 选择Show DDL选项,选择实体的表名以及数据库的类型: 就会显示该实体对应表的建表语句: 如果选择Run Query in JPA Console选项: 会开启一个控制台,可以输入并执行JPA的查询语句: 通常打开实体类或者Repository接口后,IDEA右侧会有一个JPA Designer工具窗口: 在该工具栏的上部分可以为实体添加相应类型的属性、添加相应的生命周期回调方法、索引、以及根据指定属性添加Repository的方法。例如,双击Lifecycle Callbacks下的PreRemove和PostRemove就会自动生成对应的生命周期回调方法,这些方法会在操作该实体移除前后执行。 JPA Designer工具栏中对应的选项也可以简单的在编辑区使用快捷键Alt+insert实现,这也会弹出对应的悬浮框,根据需要选择即可。
八、总结
本文主要介绍了我个人认为IDEA中使用Spring Data JPA非常有用的一些关键地方。主要是先对JPA,Spring Data有一些基础的了解,在这基础之上,使用IDEA插件提供的集成支持,可以让我们的代码以更快速的方式直接生成,避免手动编写而出现的一些错误。还有一些比较更细节的地方之后可能会再补一篇文章,如Spring Data视图Projection接口的快速创建、生成JPA的数据类型转换器以及数据库迁移等。本文只是介绍IDEA这一方面对JPA的一些支持,并不深入涉及Spring Data JPA的内容,希望能对看到的你有所帮助。另外,想了解更多Spring Data的内容,或者Spring Boot、Spring Cloud、Spring Security,可以查看我的笔记仓库和博客,也欢迎点Star,PR。 Github代码仓库 博客