jOOQ-重用SelectConditionStep

时间:2019-05-22 10:58:53

标签: java sql jooq

我有一些这样的代码:

var step =
    db.select(T1.C1).
        from(T1).
        where(T1.C2.eq(v1));

var result = step.
    and(T1.C3.eq(v2)).
    fetchOne();

if(result == null) 
    result = step.
        and(T1.C3.eq(v3)).
        fetchOne();

它可以正常工作,但是我想知道是否由于jOOQ的内部情况而避免了这种重用。

1 个答案:

答案 0 :(得分:1)

出于历史原因,DSL API的某些元素是可变的,这意味着您不应在代码中重用对中间“步骤”类型的任何引用。每个“步骤”类型的Javadoc中都提到了这一点:

  

直接从客户代码中引用XYZ *步骤类型

     

通常不建议直接从客户端代码中引用任何XYZ * Step类型,或将它们分配给局部变量。在编写动态SQL时,动态创建语句的组件并将其静态传递给DSL API通常是更好的选择。有关详细信息,请参见手册中有关动态SQL的部分:https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql

     

直接引用XYZ * Step类型的缺点:

     
      
  • 它们在可变实现上运行(自jOOQ 3.x起)
  •   
  • 当动态SQL变得复杂时,它们的组合性较差并且不容易正确使用
  •   
  • 它们的可读性较差
  •   
  • 它们在次要发行版之间可能存在二进制不兼容的更改
  •   

我建议您改用functional approach to writing dynamic SQL

Select<Result1<Integer>> fetchOne(Condition condition) {
    return db.select(T1.C1)
             .from(T1)
             .where(T1.C2.eq(v1))
             .and(condition)
             .fetchOne();
}

var result = fetchOne(T1.C3.eq(v2));

if (result == null)
    result = fetchOne(T1.C3.eq(v3));

或者,在SQL中执行所有操作以防止额外的往返行程:

var result =
db.select(T1.C1)
  .from(T1)
  .where(T1.C2.eq(v1))
  .and(T1.C3.in(v2, v3))
  .orderBy(T1.C3.sortAsc(v2, v3))
  .limit(1)
  .fetchOne()

这是使用Field.sortAsc()便捷方法。