Тестирование: несовместимость между MySQL и H2 - PullRequest
0 голосов
/ 21 июня 2019

Я пытаюсь проверить свой собственный JPA @Query с H2. Мой собственный запрос выглядит следующим образом:

  @Query(
      value = "SELECT * FROM accounts " +
              " WHERE 'account_name' LIKE LOWER(CONCAT('%', COALESCE(:searchTerm, ''), '%')) ",
      countQuery = "SELECT count(*) FROM accounts " +
                   " WHERE 'account_name' LIKE LOWER(CONCAT('%', COALESCE(:searchTerm, ''), '%')) ",
      nativeQuery = true
  )

При написании модульного теста я получаю следующую ошибку H2:

Причина: org.h2.jdbc.JdbcSQLException: таблица "ACCOUNTS" не найдена; Инструкция SQL: SELECT * FROM account, ГДЕ 'aws_account_name' LIKE Нижний предел (CONCAT ('%', COALESCE (?, ''), '%'))? [42102-197]

Я могу исправить ошибку H2, изменив синтаксис SQL, указав имя таблицы в двойных кавычках:

  @Query(
      value = "SELECT * FROM \"accounts\" " +
              " WHERE 'account_name' LIKE LOWER(CONCAT('%', COALESCE(:searchTerm, ''), '%')) ",
      countQuery = "SELECT count(*) FROM \"accounts\" " +
                   " WHERE 'account_name' LIKE LOWER(CONCAT('%', COALESCE(:searchTerm, ''), '%')) ",
      nativeQuery = true
  )

ОДНАКО, тогда мой MySQL (фактическая не тестовая среда) жалуется:

Причина: java.sql.SQLSyntaxErrorException: у вас есть ошибка в вашем Синтаксис SQL; проверьте руководство, которое соответствует вашему серверу MySQL версия для правильного синтаксиса для использования рядом с «учетными записями» ГДЕ 'account_name' LIKE LOWER (CONCAT ('%', COALESCE ('ab', ''), 'в строке 1

Как я могу проверить этот собственный запрос с MySQL и H2?

Причина, по которой я использую собственный запрос вместо JPQL, заключается в том, что мне нужно выполнять поиск без учета регистра и разрешать сопоставление "содержит".

1 Ответ

0 голосов
/ 22 июня 2019

По умолчанию MySQL распознает токен, заключенный в двойные кавычки, как строковый литерал , а не идентификатор (то есть имя таблицы или имя столбца).

Если мы изменим MySQL sql_mode для включения ANSI_QUOTES, то токен, заключенный в двойные кавычки, будет рассматриваться как идентификатор . Но это вызовет проблему в SQL, где строковые литералы заключены в двойные кавычки, а не в стандартные одинарные кавычки SQL.

Если режим совместимости H2 установлен на MySQL, то мы должны иметь возможность использовать обычные символы обратного удара MySQL для экранирования идентификаторов. * например 1013 *

 SELECT *
   FROM `accounts`
        ^        ^

Кроме того, MySQL не собирается возражать против этой конструкции:

WHERE 'aws_account_name' LIKE
      ^                ^

, но заключенный в одинарные кавычки, MySQL видит маркер 'aws_account_name' здесь как строковый литерал , а не как ссылку на столбец.

Если предполагается, что это имя столбца, мы можем использовать символы обратной связи MySQL вокруг ссылки на столбец.

Чтобы уменьшить путаницу и облегчить работу будущего читателя, мы обычно предпочитаем квалифицировать ссылки на столбцы, даже если это строго не требуется. Например, используя псевдоним короткой таблицы:

 SELECT t.*
   FROM `accounts` t
  WHERE t.`aws_account_name` LIKE ...
...