У меня есть такой код:
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.
По историческим причинам некоторые элементы DSL API являются изменяемыми, что означает, что вы не должны повторно использовать ссылки на промежуточные типы «шагов» в своем коде. Это упоминается в Javadoc каждого типа «шаг»:
Referencing XYZ*Step types directly from client code
It is usually not recommended to reference any XYZ*Step types directly from client code, or assign them to local variables. When writing dynamic SQL, creating a statement's components dynamically, and passing them to the DSL API statically is usually a better choice. See the manual's section about dynamic SQL for details: https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql.
Drawbacks of referencing the XYZ*Step types directly:
- They're operating on mutable implementations (as of jOOQ 3.x)
- They're less composable and not easy to get right when dynamic SQL gets complex
- They're less readable
- They might have binary incompatible changes between minor releases
Я рекомендую вместо этого взять функциональный подход к написанию динамического 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()
.
См. также этот пост в блоге, чтобы узнать, почему бы не ссылаться на типы XYZStep
напрямую.