Решение вашей проблемы
Вы можете преобразовать любое значение типа T
в выражение типа Field<T>
, используя DSL.val()
(обычно предпочтительнее) или DSL.inline()
Пояснение к статус-кво
На языке, который поддерживает псевдонимы типов и нетегированные объединения (например, TypeScript, Ceylon), API-интерфейс jOOQ можно определить следующим образом:
// All of these are "column expressions"
type F<T> = T | Field<T> | Select<? extends Record1<T>> | ...;
interface DSLContext {
<T1> XYZ<Record1<T1>> select(F<T1> field1);
<T1, T2> XYZ<Record1<T1, T2>> select(F<T1> field1, F<T2> field2);
<T1, T2, T3> XYZ<Record1<T1, T2, T3>> select(F<T1> field1, F<T2> field2, F<T3> field3);
}
Но, к сожалению, Java не поддерживает это. Единственная опция, которую мы должны эмулировать выше, которая позволила бы смешивать Field<T>
и T
в списках аргументов, была бы недопустимым количеством перегрузок (N ^ 22 с N = числом типов в F<T>
и 22, являющимся максимальная степень, поддерживаемая безопасностью типов jOOQ):
interface DSLContext {
// Still fine
<T1> XYZ<Record1<T1>> select(T1 f1);
<T1> XYZ<Record1<T1>> select(Field<T1> f1);
// OK-ish
<T1, T2> XYZ<Record1<T1, T2>> select(T1 f1, T2 f2);
<T1, T2> XYZ<Record1<T1, T2>> select(T1 f1, Field<T2> f2);
<T1, T2> XYZ<Record1<T1, T2>> select(Field<T1> f1, T2 f2);
<T1, T2> XYZ<Record1<T1, T2>> select(Field<T1> f1, Field<T2> f2);
// Problems start here
<T1, T2, T3> XYZ<Record1<T1, T2, T3>> select(T1 f1, T2 f2, T3 f3);
<T1, T2, T3> XYZ<Record1<T1, T2, T3>> select(T1 f1, T2 f2, Field<T3> f3);
<T1, T2, T3> XYZ<Record1<T1, T2, T3>> select(T1 f1, Field<T2> f2, T3 f3);
<T1, T2, T3> XYZ<Record1<T1, T2, T3>> select(T1 f1, Field<T2> f2, Field<T3> f3);
<T1, T2, T3> XYZ<Record1<T1, T2, T3>> select(Field<T1> f1, T2 f2, T3 f3);
<T1, T2, T3> XYZ<Record1<T1, T2, T3>> select(Field<T1> f1, T2 f2, Field<T3> f3);
<T1, T2, T3> XYZ<Record1<T1, T2, T3>> select(Field<T1> f1, Field<T2> f2, T3 f3);
<T1, T2, T3> XYZ<Record1<T1, T2, T3>> select(Field<T1> f1, Field<T2> f2, Field<T3> f3);
}
Из-за этой непомерной сложности jOOQ обычно предлагает API только для «всех значений связывания» или «всех выражений». В случае select()
случай «всех переменных связывания» настолько редок, что мы решили его опустить:
interface DSLContext {
<T1> XYZ<Record1<T1>> select(Field<T1> f1);
<T1, T2> XYZ<Record1<T1, T2>> select(Field<T1> f1, Field<T2> f2);
<T1, T2, T3> XYZ<Record1<T1, T2, T3>> select(Field<T1> f1, Field<T2> f2, Field<T3> f3);
}