V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
f0rb
V2EX  ›  Java

DoytoQuery vs SpringDataJPA

  •  
  •   f0rb · 20 小时 4 分钟前 · 451 次点击

    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 的核心功能。

    4 条回复    2026-03-05 17:32:13 +08:00
    beginor
        1
    beginor  
       18 小时 40 分钟前
    建议可以参考一下 NHibernate 或者 EntityFramework 的 Linq 查询的实现,C#这边 Linq 已经快 20 年了,不知道为什么 Java 这边一直没有类似的东西出现,对 Java 不熟悉,不好评价。
    f0rb
        2
    f0rb  
    OP
       14 小时 15 分钟前
    @beginor Linq 这种需要编译期支持的就算了吧,Linq 真这么好咋没有其他任何编程语言跟进呢?
    shuangbiaog
        3
    shuangbiaog  
       13 小时 8 分钟前
    类似 mybatis-plus 的条件构造器?
    f0rb
        4
    f0rb  
    OP
       12 小时 37 分钟前
    @shuangbiaog 纯依赖查询对象实现自动化构建,一行方法都不用写,这里有个对比仓库:
    https://github.com/f0rb/java-orm-comparison
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   955 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 22:09 · PVG 06:09 · LAX 14:09 · JFK 17:09
    ♥ Do have faith in what you're doing.