jOOQ: Как создать запрос на выборку с оператором MySQL «BINARY»?

Вопрос

Как я могу создать любой из следующих двух (эквивалентных) операторов MySQL с помощью jOOQ?

SELECT * FROM `tbl` WHERE `col` = BINARY 'foobar   ';
SELECT * FROM `tbl` WHERE `col` = CAST('foobar   ' AS BINARY);

Фон

Я хотел бы сравнить произвольные строки, возможно, включая (значительные) конечные пробелы. К сожалению, MySQL по умолчанию игнорирует конечные пробелы при сравнении с =. Насколько я понял из этот вопрос, такие сравнения возможны только с использованием оператор BINARY в MySQL.

Что я уже пробовал

Я пытался использовать метод DSL.cast() в jOOQ:

myDb.selectFrom(TBL)
  .where(TBL.COL
     .eq(DSL.cast("foobar   ", MySQLDataType.BINARY)))
  .fetchOne();
// → compiler error: “The method eq(String) in the type Field<String> is not
//   applicable for the arguments (Field<byte[]>)”

myDb.selectFrom(TBL)
  .where(DSL.cast(TBL.COL, MySQLDataType.BINARY)
     .eq("foobar   "))
  .fetchOne();
// → compiler error: “The method eq(byte[]) in the type Field<byte[]> is not
//   applicable for the arguments”

myDb.selectFrom(TBL)
  .where(DSL.cast(TBL.COL, MySQLDataType.BINARY)
     .eq(DSL.cast("foobar   ", MySQLDataType.BINARY)))
  .fetchOne();
// → runtime error: “org.jooq.exception.DataTypeException: Cannot convert from
//   foobar    (class java.lang.String) to class [B”

Обходной путь

Моим последним средством было бы изменить мой запрос, чтобы использовать LIKE вместо =. Однако это был бы хак, так как тогда мне пришлось бы всегда сначала заключать в кавычки любые подстановочные знаки в моей строке, и я также столкнулся бы со штрафом за производительность :-|


person Chriki    schedule 05.05.2014    source источник


Ответы (1)


Ваш третий пример должен работать и, вероятно, является ошибкой, которую я зарегистрировал как Issue #3255:

myDb.selectFrom(TBL)
  .where(DSL.cast(TBL.COL, MySQLDataType.BINARY)
     .eq(DSL.cast("foobar   ", MySQLDataType.BINARY)))
  .fetchOne();

Как всегда, если вам не хватает функции в jOOQ или вы столкнулись с ошибкой, вы можете прибегнуть к использованию простого SQL, как описано здесь:

Пример для работы В вашем случае:

myDb.selectFrom(TBL)
  .where(TBL.COL
     .eq(DSL.field("BINARY ?", String.class, "foobar   ")))
  .fetchOne();

Or:

myDb.selectFrom(TBL)
  .where("{0} = BINARY {1}", TBL.COL, DSL.val("foobar   "))
  .fetchOne();
person Lukas Eder    schedule 08.05.2014