开发工具
English

spring-data-jpa-extra:让 JPA 也能写动态 SQL,MyBatis 用户看了都沉默

Spring Data JPA 扩展库,401 star,支持模板化动态查询(Freemarker/Velocity),像 MyBatis 一样灵活写 SQL,同时保留 JPA 的简洁。

javaspring-bootjpasqlmybatisfreemarker

广告

spring-data-jpa-extra:让 JPA 也能写动态 SQL,MyBatis 用户看了都沉默

用 Spring Data JPA 的人一定有过这种纠结:写简单 CRUD 是真爽,一行代码搞定。但一旦遇到复杂查询、动态条件拼接,JPA 的 Specification 和 QueryDSL 就让人觉得还不如手写 SQL。spring-data-jpa-extra 这个库,就是想让你「鱼与熊掌兼得」——保留 JPA 的简洁,同时能像 MyBatis 一样灵活写动态 SQL。

项目背景

这是个 Java 项目,401 star,不算大火但实用性很强。作者的想法很直接:JPA 的 @Query 注解只能写静态 JPQL/SQL,动态条件不支持。而 MyBatis 的 XML 模板虽然灵活,但得维护一套 XML 文件。能不能把两者结合起来?于是就有了这个扩展——在 JPA 里引入模板引擎(Freemarker、Velocity),实现动态 SQL。

项目已经支持 Spring Boot 2+ 和 Spring 5+,master 分支维护还算活跃。

核心功能拆解

模板化动态查询。 这是核心能力。你可以在 resources 目录下放 .ftl(Freemarker)或 .vm(Velocity)模板文件,然后在 Repository 接口里引用。模板里可以写 if、foreach 这些逻辑,根据传入的参数动态拼接 SQL。比如一个用户搜索接口,用户名可选、时间范围可选、状态可选,用模板写比 Specification 优雅多了。

兼容 JPA 原生特性。 不是另起炉灶,而是扩展。你仍然可以用 JpaRepository 的所有方法,@Entity、@Table 这些注解也完全兼容。只是多了个 @TemplateQuery 注解,指定模板文件路径就行。对已有 JPA 项目的侵入性很小。

多模板引擎支持。 默认支持 Freemarker 和 Velocity,两种语法任选。Freemarker 功能更强,Velocity 更轻量。我试了下 Freemarker 版本,语法跟 MyBatis 的 XML 动态标签很像,上手很快。

分页和排序无缝对接。 返回类型可以是 Page、Slice、List,跟普通 JPA 查询完全一样。Spring Data 的分页参数(Pageable)直接传进去就行,不需要额外处理。

快速上手

Maven 依赖:

<dependency>
    <groupId>com.slyak</groupId>
    <artifactId>spring-data-jpa-extra</artifactId>
    <version>3.0.0</version>
</dependency>

Repository 接口:

public interface UserRepository extends GenericJpaRepository<User, Long> {
    @TemplateQuery
    List<User> findByQuery(UserQuery query);
}

模板文件 resources/META-INF/user/UserRepository/findByQuery.ftl

SELECT * FROM user WHERE 1=1
<#if query.name??>
  AND name LIKE '%${query.name}%'
</#if>
<#if query.status??>
  AND status = ${query.status}
</#if>

然后正常调用 userRepository.findByQuery(query) 就行。整个流程跟 MyBatis 几乎一样,但底层还是 JPA。

优缺点分析

优点:

  • 动态 SQL 写法直观,比 Specification 和 Criteria API 简单太多
  • 不破坏现有 JPA 项目结构,增量引入成本低
  • 模板文件单独管理,SQL 集中存放,维护方便
  • 支持主流模板引擎,选择灵活
  • 分页排序原生支持,不用自己封装

缺点:

  • 401 star,社区比较小,遇到问题可能搜不到解决方案
  • 模板文件放 resources 里,项目大了之后文件管理有点乱
  • 没有官方 Spring Boot Starter,需要自己配 Bean
  • 错误提示不够友好,模板写错了报错信息比较模糊
  • 跟 QueryDSL 比,类型安全没了,字段名写错要到运行时才暴露

跟同类产品比比

方案动态 SQL类型安全学习成本侵入性社区活跃度
spring-data-jpa-extra✅ 模板
QueryDSL✅ DSL
JPA Specification✅ API
MyBatis✅ XML/注解极高
jOOQ✅ DSL

跟 MyBatis 比,它的优势是不用维护一套独立的 ORM 体系,JPA 的缓存、关联映射这些还能继续用。跟 QueryDSL 比,它的优势是写动态 SQL 更直观,不用学一套 DSL 语法。但如果你的项目已经深度用了 QueryDSL,迁移过来意义不大。

适合谁用

三类场景比较合适:

  1. 已有 JPA 项目,偶尔需要复杂查询——不值得为了几个查询引入 MyBatis,用这个扩展刚好
  2. 团队熟悉 MyBatis 语法,想试 JPA——模板写法降低迁移门槛
  3. 中小型项目,不想引入 QueryDSL——QueryDSL 配置复杂,这个轻量很多

我实际用下来的感受是,这个库确实解决了 JPA 的一个真实痛点。但它的问题也很明显: star 数低意味着社区支持有限,生产环境用之前得自己把坑踩一遍。如果是核心系统的关键查询,我可能还是会选 QueryDSL 或者干脆上 MyBatis。但如果是内部工具、后台管理系统这种场景,用它完全够用了,而且省不少事。


关于作者

柳钉鱼,全栈开发者,GitHub 重度用户。过去 3 年 Star 了 900+ 仓库,这里只写我真正用过或深度调研过的工具。

📧 发现好工具想推荐?发邮件到 [email protected]

广告

相关文章