Вопрос

Я представляю уровень 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, который будет работать на двух БД, является сложной задачей. Время от времени это может казаться почти невозможным.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top