Спящий режим на Oracle И SQLServer
-
05-07-2019 - |
Вопрос
Я представляю уровень DAO в нашем приложении, которое в настоящее время работает на SQL Server, потому что мне нужно перенести его на Oracle.
Я хотел бы использовать Hibernate и написать фабрику (или использовать внедрение зависимостей), чтобы выбрать правильные DAO в соответствии с конфигурацией развертывания.Каковы лучшие практики в этом случае?Должен ли я иметь два пакета с разными файлами hibernate.cfg.xml и *.hbm.xml и соответственно выбирать их на своей фабрике?Есть ли шанс, что мои DAO будут корректно работать с обеими СУБД без (слишком больших) хлопот?
Решение
Предполагая, что имена таблиц и столбцы между ними совпадают, вы сможете использовать одни и те же файлы hbm.xml
. Однако вам, безусловно, нужно будет указать другое значение конфигурации Hibernate ( hibernate.cfg.xml
), поскольку вам нужно будет изменить диалект Hibernate с SQLServer на Oracle.
Если между ними есть небольшие различия в именах, я бы создал два набора файлов сопоставления - по одному на сервер базы данных - и упаковал их в отдельные файлы JAR (например, yourproject-sqlserver-mappings.jar
и yourproject-oracle-mappings.jar
) и разверните приложение с одним JAR или другим в зависимости от среды.
Другие советы
Я сделал это для клиента некоторое время назад - при развертывании в зависимости от набора свойств в файле production.properties
я заменил hibernate.dialect
в Файл cfg
, использующий Ant (вы можете использовать любой xml трансформер). Однако это будет работать только в том случае, если код Hibernate является бесшовным между обеими БД, т.е. без вызовов функций, специфичных для БД, и т. Д. В HQL / JPAQL есть стандартные вызовы функций, которые помогают в этом отношении, например UPPER (s)
, ДЛИНА (и)
и т. Д.
Если реализации db обязательно должны отличаться, вам нужно будет сделать что-то вроде того, что предложил @matt.
Я работал над приложением, которое поддерживает множество баз данных (Oracle, Informix, SQL Server, MySQL).У нас есть один файл конфигурации и один набор сопоставлений.Мы используем jndi для подключения к базе данных, поэтому нам не приходится иметь дело с разными URL-адресами подключения в приложении.Когда мы инициализируем SessionFactory, у нас есть метод, который определяет тип базы данных на основе базового соединения.Например, вручную получите соединение через JNDI, а затем используйте Connection.getMetaData().getDatabaseProductName(), чтобы узнать, что представляет собой база данных.Вы также можете использовать переменную среды контейнера, чтобы явно установить ее.Затем установите диалект с помощью Configuration.setProperty(Environment.DIALECT, deducedDialect) и инициализируйте SessionFactory как обычно.
Некоторые вещи, с которыми вам придется иметь дело:
- Генерация первичного ключа.Мы используем настроенную версию стратегии TableGenerator, поэтому у нас есть одна ключевая таблица со столбцами для имени таблицы и следующего ключа.Таким образом, каждая база данных может использовать одну и ту же стратегию, а не последовательность в Oracle, встроенную в SQL Server и т. д.
- Функции, специфичные для баз данных.Мы избегаем их, когда это возможно.Hibernate-диалекты обрабатывают наиболее распространенные из них.Иногда нам придется добавлять свои собственные классы диалектов, например.Арифметика дат довольно нестандартна, поэтому мы просто придумаем имя функции и сопоставим его со способом выполнения каждой базы данных.
- Генерация схемы — мы используем класс генерации схемы Hibernate — он работает с диалектами для создания правильного DDL для каждого типа базы данных и заставляет базу данных соответствовать сопоставлениям.Вы должны знать ключевые слова для каждой базы данных, например.не пытайтесь создать таблицу USER в Oracle (подойдет USERS) или таблицу TRANSLATION в MySQL.
Здесь есть таблица, отображающая различия между Oracle и SQLServer: http://psoug.org/ ссылка / sqlserver.html р>
На мой взгляд, самые большие подводные камни: 1) Даты. Функции и механика совершенно разные. Вам придется использовать разные коды для каждой БД. 2) Генерация ключей - Oracle и SQLServer используют разные механизмы, и если вы пытаетесь избежать "родного" генерация в целом, имея свою собственную таблицу ключей - ну, вы просто полностью сериализовали все свои «вставки». Не хорошо для производительности. 3) Параллельность / блокировка немного отличается. Части кода, чувствительные к производительности, вероятно, будут отличаться для каждой БД. 4) Oracle чувствителен к регистру, SQLServer - нет. Вы должны быть осторожны с этим.
Есть еще много :) Написание кода SQL, который будет работать на двух БД, является сложной задачей. Время от времени это может казаться почти невозможным.