Спящий режим на Oracle и SQLServer - PullRequest
2 голосов
/ 21 октября 2009

Я представляю слой DAO в нашем приложении, в настоящее время работающем на SQL Server, потому что мне нужно перенести его на Oracle.

Я бы хотел использовать Hibernate и написать фабрику (или использовать внедрение зависимостей), чтобы выбрать правильные DAO в соответствии с конфигурацией развертывания. Каковы лучшие практики в этом случае? Должен ли я иметь два пакета с разными файлами hibernate.cfg.xml и * .hbm.xml и выбрать их соответствующим образом на своей фабрике? Есть ли вероятность того, что мои DAO будут работать правильно с обеими СУБД без лишних хлопот?

Ответы [ 4 ]

3 голосов
/ 22 октября 2009

Здесь есть таблица, отображающая различия между Oracle и SQLServer: http://psoug.org/reference/sqlserver.html

На мой взгляд, самые большие подводные камни: 1) Даты. Функции и механика совершенно разные. Вам придется использовать разные коды для каждой БД. 2) Генерация ключей - Oracle и SQLServer используют разные механизмы, и если вы пытаетесь вообще избежать «родного» поколения, имея собственную таблицу ключей - ну, вы просто полностью сериализовали все свои «вставки». Не хорошо для производительности. 3) Параллельность / блокировка немного отличается. Части кода, чувствительные к производительности, вероятно, будут отличаться для каждой БД. 4) Oracle чувствителен к регистру, SQLServer - нет. Вы должны быть осторожны с этим.

Есть еще много :) Написание кода SQL, который будет работать на двух БД, является сложной задачей. Время от времени это может казаться почти невозможным.

3 голосов
/ 21 октября 2009

Я сделал это для клиента некоторое время назад - при развертывании в зависимости от набора свойств в файле production.properties я изменил hibernate.dialect в файле cfg с помощью Ant (вы можете использовать любой xml-преобразователь) , Однако это будет работать только в том случае, если код Hibernate является бесшовным между обеими БД, то есть без вызовов функций, специфичных для БД, и т. Д. В HQL / JPAQL есть стандартные вызовы функций, которые помогают в этом отношении, например UPPER(s), LENGTH(s) и т. Д.

Если реализации db обязательно должны отличаться, вам придется сделать что-то вроде того, что предложил @matt.

3 голосов
/ 21 октября 2009

Я работал над приложением, которое поддерживает множество баз данных (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.
3 голосов
/ 21 октября 2009

Предполагая, что имена таблиц и столбцы между ними совпадают, вы сможете использовать одинаковые hbm.xml файлы. Однако вам, безусловно, нужно будет указать другое значение конфигурации Hibernate (hibernate.cfg.xml), поскольку вам нужно будет изменить диалект Hibernate с SQLServer на Oracle.

Если между этими двумя именами есть небольшие различия, я бы создал два набора файлов сопоставления - по одному на сервер базы данных - и упаковал их в отдельные JAR-файлы (такие как yourproject-sqlserver-mappings.jar и yourproject-oracle-mappings.jar) и развернул приложение с одним JAR или другим в зависимости от среды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...