Код: Выделить всё
public class CustomBooleanConverter implements Converter{
@Override
public Boolean from(String s) {
if (s == null) {
return null;
}
return s.equals("true");
}
@Override
public String to(Boolean aBoolean) {
if (aBoolean == null) {
return null;
}
return aBoolean.booleanValue() ? "true" : "false";
}
@Override
public Class fromType() {
return String.class;
}
@Override
public Class toType() {
return Boolean.class;
}
}
И объявите его для использования в конфигурации maven следующим образом:
java.lang.Boolean
com.jooq.config.CustomBooleanBinding
.*\.AMENDABLE
И это будет класс пользовательской привязки:
public class CustomBooleanBinding implements Binding {
@Override
public Converter converter() {
return new CustomBooleanConverter ();
}
@Override
public void sql(BindingSQLContext bindingSQLContext) throws SQLException {
String converted = converter().to(bindingSQLContext.value());
if (bindingSQLContext.render().paramType() == ParamType.INLINED){
if (converted == null) {
bindingSQLContext.render().sql("NULL");
} else {
bindingSQLContext.render().sql("\'"+converted+"\'");
}
} else {
bindingSQLContext.render().sql(bindingSQLContext.variable());
}
}
@Override
public void register(BindingRegisterContext bindingRegisterContext) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void set(BindingSetStatementContext bindingSetStatementContext) throws SQLException {
String value = bindingSetStatementContext.convert(converter()).value();
bindingSetStatementContext.statement().setString(bindingSetStatementContext.index(),
value == null ? null : value);
}
@Override
public void set(BindingSetSQLOutputContext bindingSetSQLOutputContext) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void get(BindingGetResultSetContext bindingGetResultSetContext) throws SQLException {
bindingGetResultSetContext.convert(converter())
.value(bindingGetResultSetContext.resultSet().getString(bindingGetResultSetContext.index()));
}
@Override
public void get(BindingGetStatementContext bindingGetStatementContext) throws SQLException {
bindingGetStatementContext.convert(converter());
}
@Override
public void get(BindingGetSQLInputContext bindingGetSQLInputContext) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
}
Файлы, созданные JOOQ, выглядят нормально:
/**
* The column TABLEXX.AMENDABLE
*/
public final TableField AMENDABLE = createField(DSL.name("AMENDABLE"), SQLDataType.VARCHAR(6), this, "", new CustomBooleanBinding());
Но при построении динамического запроса с использованием SelectWhereStep и добавлении условия, в котором поле называется AMENDABLE с логическим типом и значением true, визуализируемый SQL выглядит следующим образом:
select alias_90892522.OTHER COLUMN,
......,
alias_90892522.AMENDABLE
from (
select OTHER COLUMN,
......,
AMENDABLE
from tableXX
) alias_90892522
where
(
"alias_90892522"."OTHER COLUMN" = '0005698'
and "alias_90892522"."AMENDABLE" = 1
)
Код Java выглядит так:
SelectConditionStep subquery= select(tableXX.Other_column,tableXX.amendable ).from(tableXX);
Table table = subquery.asTable;
SelectWhereStep query = selectFrom(table);
query.where(table.field("OTHER_COLUM", String.class).equal("0005698"))
query.where(table.field("AMENDABLE,Boolean.class).equal(true));
Это сделано таким образом, поскольку запросы строятся динамически на основе аннотаций для таблиц и столбцов.
Я отлаживал код, и класс CustomBooleanBinding никогда не вызывается.
Есть подсказки, что я делаю неправильно?
Версия JOOQ — 3.14.9
Я ожидаю, что JOOQ будет использовать пользовательскую привязку преобразователь логического типа всякий раз, когда какой-либо столбец имеет имя «AMENDABLE» в соответствии с реализованной конфигурацией. Но вместо этого JOOQ использует логическое преобразование логического значения в целое число по умолчанию (true = 1), и я ожидаю преобразования логического значения в строку, например ( true = "true").
это делает выполнение sql завершается неудачей во время выполнения, так как столбец имеет значение VARCHARD, но JOOQ использует значение NUMBER
** Я провел небольшой тест, если я изменю поток и добавлю условиеwhere во внутренний запрос, пользовательское привязка вызывается, и она работает. Есть подсказки, почему?
select alias_90892522.OTHER COLUMN,
......,
alias_90892522.AMENDABLE
from (
select OTHER COLUMN,
......,
AMENDABLE
from tableXX
where tableXX.AMENDABLE = 'true'
) alias_90892522
where
(
"alias_90892522"."OTHER COLUMN" = '0005698'
)
Подробнее здесь: https://stackoverflow.com/questions/785 ... -dynamic-q