我有一些这样的代码:
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的内部情况而避免了这种重用。
答案 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()
便捷方法。