#java #mysql #h2
#java #mysql #h2
Вопрос:
Когда я использовал базу данных MySQL для своего веб-проекта, если я выполняю запрос SELECT Date(now())
, он выдает мне текущую дату. Недавно во время выполнения некоторого модульного теста я решил использовать in-memory H2 database
для повышения производительности. И теперь, если я использую запрос SELECT Date(now())
, он выдает мне следующую ошибку
org.h2.jdbc.JdbcSQLException: Function "DATE" not found; SQL statement:
SELECT Date(now()) [90022-178]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:344)
at org.h2.message.DbException.get(DbException.java:178)
at org.h2.message.DbException.get(DbException.java:154)
at org.h2.command.Parser.readJavaFunction(Parser.java:2326)
at org.h2.command.Parser.readFunction(Parser.java:2378)
at org.h2.command.Parser.readTerm(Parser.java:2712)
at org.h2.command.Parser.readFactor(Parser.java:2244)
at org.h2.command.Parser.readSum(Parser.java:2231)
at org.h2.command.Parser.readConcat(Parser.java:2201)
Итак, как мне использовать функции MySQL в базе данных H2
Ответ №1:
С помощью H2 вам нужно использовать CURRENT_DATE
функцию вместо того, что вы используете.
Как отмечали другие, существует стандартный SQL и некоторые расширения к нему (которые различаются у разных поставщиков СУБД). CURRENT_DATE
Является частью стандарта, DATE
функция — нет. Поэтому просто используйте стандартную функцию, и у вас все будет хорошо как с H2, так и с MySQL.
Комментарии:
1. В этом случае мне нужно много изменить свой код, разместить какую-либо альтернативу без изменения основного объема кода?
2. @M.Sharma Сам MySQL также поддерживает
CURRENT_DATE
, и это в стандарте SQL, лучше исправить это один раз, чем продолжать жить с устаревшими несовместимостями3. Есть ли какой-либо другой способ, если я хочу использовать Date() вместо чего-либо другого
4. Нет, у H2 просто нет
DATE
функции. Если вам нужен код, который работает более чем в одной базе данных, лучше всего использовать только ANSI SQL.5. H2 позволяет создавать пользовательские функции с
CREATE ALIAS
синтаксисом и предоставлять собственную реализацию Java.
Ответ №2:
К сожалению, именно с такой трудностью вы сталкиваетесь при замене баз данных. Хотя JDBC и большинство операторов SQL будут совместимы, у вас возникнут проблемы со встроенными функциями, которые различаются у разных поставщиков баз данных.
Есть несколько подходов к решению этой проблемы:
-
Поместите все инструкции SQL во внешний ресурс, такой как файл свойств, и попросите модульные тесты загрузить другой ресурс. Таким образом, производственный код увидит инструкции MySQL, а код модульного тестирования увидит инструкции H2.
-
Просто используйте MySQL. Не беспокойтесь о производительности, модульные тесты не критичны к производительности. Используйте фреймворк, такой как DBUnit
-
Вообще не включайте базу данных в модульные тесты. Поскольку сам JDBC не тестируется, вы можете предположить, что он работает, и вместо этого издеваться над ним с помощью фреймворка, такого как Mockito
Ответ №3:
Вы должны запустить H2 в режиме совместимости с MySQL (= диалект MySQL) без изменения ваших текущих запросов SQL.
Редактировать:
Итак, как мне использовать функции MySQL в базе данных H2
Что касается поддержки DATE()
функции, вы могли бы использовать CREATE ALIAS
и предоставить свою собственную реализацию. Прочитайте в разделе Определяемые пользователем функции и хранимые процедуры для примера, это довольно просто.
На доске обсуждения H2 также есть этот старый поток по этой теме с реализацией функций даты MySQL, но прочитайте поток, чтобы узнать, как их использовать.
Комментарии:
1. Режим совместимости не обеспечивает поддержку встроенных функций