DoytoQuery vs SpringDataJPA

1 天前
 f0rb

SpringDataJPA 支持通过 findBy 方法构建查询语句,然而 findBy 方法构建的查询条件是固定的,不支持忽略值为 null 的参数对应的查询条件,这导致我们需要为每一组参数组合定义一个 findBy 方法。例如:

findByAuthor
findByAuthorAndPublishedYearGreaterThan
findByAuthorAndPublishedYearLessThan
findByAuthorAndPublishedYearGreaterThanAndPublishedYearLessThan

当条件变多时,方法名会变长,参数也会变多,并触发“长参数”坏味道。解决这一问题的重构方法是“引入参数对象”,即把所有的参数定义在一个对象里。同时,我们把 findBy 的方法名中对应查询条件的部分作为这个对象的字段名称,我们便能为每个字段构建一个查询条件,并且根据对象的赋值情况,动态地组合非空字段对应的查询条件组合为查询子句。

public class BookQuery {
    String author;
    Integer publishedYearGreaterThan;
    Integer publishedYearLessThan;
    //...
}

基于此对象,我们可以把所有的 findBy 方法合并为一个泛型方法,从而简化查询接口的设计。

public class CrudRepository<E, I, Q> {
    List<E> findBy(Q query);
    //...
}

提出查询对象这一概念,并利用它来解决动态查询问题,正是 DoytoQuery 的核心功能。

594 次点击
所在节点    Java
6 条回复
beginor
1 天前
建议可以参考一下 NHibernate 或者 EntityFramework 的 Linq 查询的实现,C#这边 Linq 已经快 20 年了,不知道为什么 Java 这边一直没有类似的东西出现,对 Java 不熟悉,不好评价。
f0rb
1 天前
@beginor Linq 这种需要编译期支持的就算了吧,Linq 真这么好咋没有其他任何编程语言跟进呢?
shuangbiaog
1 天前
类似 mybatis-plus 的条件构造器?
f0rb
1 天前
@shuangbiaog 纯依赖查询对象实现自动化构建,一行方法都不用写,这里有个对比仓库:
https://github.com/f0rb/java-orm-comparison
beginor
6 小时 17 分钟前
@f0rb 那 jpa 的这些方法是不是也依赖编译器呢?
beginor
6 小时 14 分钟前
@beginor linq 其实不依赖编译器编,因为 linq 表达式树不需要编译,是动态解释表达式树,转换为对应的 SQL 语句,依赖的是类型

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1195941

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX