1. 概述
JPA Buddy是一个广泛使用的IntelliJ IDEA插件,面向使用JPA数据模型和相关技术(如Spring DataJPA,DB版本控制工具(Flyway,Liquibase),MapStruct等)的新手和有经验的开发人员。该插件提供了可视化设计器、代码生成和其他检查,这些检查应根据 JPA 的最佳实践简化开发并改进代码。
该插件在IntelliJ IDEA的社区和终极版本下工作,并使用“免费增值”模型。大多数功能都是免费提供的,我们需要购买订阅才能访问付费功能。
在本教程中,我们将介绍插件的主要功能,并了解如何在应用程序开发周期中使用它们。例如,我们将使用流行的参考应用程序 - “Spring PetClinic”。
2. 入门
我们可以在将 JPA 依赖项添加到应用程序源代码时自动激活 JPA 好友。该插件在“推荐的 InteiilJ 插件”列表中,因此即使我们没有安装它,IDEA 也会建议我们这样做。我们还可以从IntelliJ的市场安装插件:
JPA 好友功能可能因附加到应用程序的库而异。例如,如果我们既没有连接 Liquibase 也没有连接 Flyway,我们将看不到用于生成数据库版本控制脚本的菜单。
3. 与 JPA 实体合作
通常,应用程序开发从数据模型开始。JPA Buddy 提供了一个可视化设计器和组件面板,允许我们创建一个实体并向其添加基本属性和关联。我们可以从上下文菜单或 JPA 结构工具窗口调用相应的操作:
如果我们需要添加或编辑实体属性,可以使用 JPA 调色板和检查器。要添加属性,我们需要双击它或执行拖放。可视化编辑器允许我们定义属性属性:
要编辑实体的属性,我们可以使用 JPA 检查器。根据 JPA 规范,检查器允许我们查看和编辑实体属性的几乎所有选项。编辑器是双向工作的:当我们更新属性的属性时,代码也会更新。反之亦然,当实体的代码更新时,所有更改都会反映在检查器中。
3.1. 龙目岛支持
根据 JPA 规范,实体应该具有属性的 getter 和 setter,这通常被视为“样板”代码。龙目岛是一个流行的库,它允许我们避免编写样板并将其替换为几个注释。许多开发人员在 JPA 实体定义中使用 Lombok,因此 JPA Buddy 完全支持它。我们可以在 JPA 检查器中编辑与龙目岛相关的属性:
插件功能不仅限于检查和编辑。支持的重要部分是检查。某些龙目岛注释在与 JPA 一起使用时可能会导致性能问题或意外错误。例如,使用@ToString注可能会导致LazyInitException,因为它使用对象字符串表示形式的所有属性,包括惰性属性。
JPA Buddy 显示针对此类情况的警告并提供快速修复,它帮助我们避免 JPA 代码中的错误:
4.DB Liquibase和Flyway的迁移
要从 JPA 数据模型创建数据库,我们通常使用数据库版本控制工具;Liquibase和Flyway是该领域的两个重要参与者。数据库迁移过程中最容易出错的部分是根据 JPA 实体的更改编写迁移脚本。JPA Buddy为Liquibase和Flyway提供了模式差异脚本生成。该插件可以将现有数据库模式与 JPA 模型甚至两个模式进行比较:
除此之外,JPA Buddy 还提供脚本自动完成和智能预览。在此模式下,插件会分析生成的脚本,如果更改可能导致目标数据源在更新时失败,则会显示警告:
5. 弹簧数据JPA支持
创建数据模型后,下一步是实现数据访问存储库。Spring Data JPA可能是最流行的框架。JPA Buddy 允许我们根据实体定义生成新的存储库。在存储库代码中,我们可以使用 JPA 调色板使用可视化工具在存储库代码中创建各种派生方法和查询:
对于每种方法,我们都可以使用 JPA 检查器更改其属性。该插件允许我们添加分页和排序,并为方法的返回数据类型创建投影:
一个更有用的功能是查询提取。有时,派生方法名称对于像这样复杂的查询来说可能会变得太长:
List<Owner> findDistinctByFirstNameIgnoreCaseOrLastNameIgnoreCaseOrPets_NameIgnoreCaseAllIgnoreCaseOrderByFirstNameAsc(
String firstName, String lastName, String name);
JPA Buddy 分析派生的方法名称,并允许我们通过重命名 JPQL 查询并将其移动到@Query注释来重构它:
@Query("select distinct o from Owner o left join o.pets pets " +
"where upper(o.firstName) = upper(:firstName) " +
"or upper(o.lastName) = upper(:lastName) " +
"or upper(pets.name) = upper(:name) " +
"order by o.firstName")
List<Owner> findByAnyName(@Param("firstName") String firstName,
@Param("lastName") String lastName,
@Param("name") String name);
6. 基于数据库表的实体生成
数据通常比代码更长久,因此当我们在现有数据库上构建 JPA 数据层时,我们需要基于当前表创建 JPA 实体。JPA Buddy 提供了此功能,并允许开发人员以“挑选”的方式创建实体,逐个选择表:
与现有解决方案相比,该插件执行“智能”生成并尝试检测实体之间的关联。即使对于没有列支持的OneToMany和ManyToMore实体,我们也将生成相应的属性:
JPA Buddy 生成“空”实体,其中只有一个 ID 列,正文中有一个 TODO 注释,用于此类关联。通过单击此 TODO,我们可以为现有实体运行列导入过程:
7. DTO 和映射器生成
DTO是一种有价值的设计模式,用于传递我们无法直接映射到JPA实体的数据的情况。例如,在创建 REST API 时,我们可能只想公开一些实体属性。
JPA Buddy可以使用MapStruct库生成DTO和映射器。我们需要做的就是为生成的 DTO 选择所需的属性:
该插件生成 DTO 和映射器,包括关联的正确映射。JPA Buddy在这种情况下也支持龙目岛,并为DTO生成适当的注释:
@Data
public class OwnerDto implements Serializable {
private final Integer id;
@NotEmpty
private final String firstName;
@NotEmpty
private final String lastName;
private final List<PetDto> pets;
}
8. 简约模式
JPA Buddy有一个友好的UI,但对于那些喜欢IntelliJ IDEA中“集中”视图的人来说,该插件提供了“简约模式”。我们可以隐藏所有工具窗口,并且仅将键盘用于实体生成、Spring Data JPA 存储库创建和编辑、调用 DTO 创建向导等:
9. 结论
JPA Buddy 提供了一组强大的工具,使 JPA 开发更容易。该插件的好处是它不仅支持JPA,还支持数据访问层开发中使用的相关库:Spring Data JPA,MapStruct,Lombok和DB版本控制解决方案。
如果我们考虑 IntelliJ IDEA 社区,这个插件可以显着简化 JPA 的工作。IDEA Ultimate用户可以从捆绑的插件中获得一些JPA Buddy功能,以获得JPA和Spring框架支持。尽管如此,看起来数据库版本控制脚本生成和 DTO 创建功能在数据库开发自动化中仍然是独一无二的。