Миграция от рукописного слоя персистентности до ORM

Мы в настоящее время оцениваем опции для миграции от рукописного слоя персистентности до ORM.

У нас есть набор постоянных объектов прежней версии (~200), та реализация простой интерфейс как это:

interface JDBC {
    public long getId();
    public void setId(long id);
    public void retrieve();
    public void setDataSource(DataSource ds);
}

Когда retrieve() назван, объект заполняет себя путем издания рукописных SQL-запросов к соединению, обеспеченному с помощью идентификатора, который это получило в методе set (это обычно - единственный параметр к запросу). Это управляет своими операторами, наборами результатов, и т.д. само. Некоторые объекты имеют специальные разновидности retrive() метод, как retrieveByName(), в этом случае другой SQL выпущен.

Запросы могли быть довольно сложными, мы часто присоединяемся к нескольким таблицам, чтобы заполнить наборы, представляющие отношения к другим объектам, иногда присоединяться, запросы выпущены по запросу в определенном методе считывания (ленивая загрузка). Так в основном мы реализовали большую часть функциональности ORM вручную.

Причиной этого была производительность. У нас есть очень сильные требования для скорости, и назад в 2005 (когда этот код был написан), тесты производительности показали, что ни один из основных ORMs не был то, что быстро как рукописный SQL.

Проблемы, с которыми мы сталкиваемся теперь, когда заставляют нас думать о ORM:

  • Большинство путей в этом коде хорошо протестировано и стабильно. Однако некоторый редко используемый код подвержен набору результатов и утечкам соединения, которые очень трудно обнаружить
  • Мы в настоящее время сжимаем некоторую дополнительную производительность путем добавления кэширующийся к нашему слою персистентности, и это - огромная боль для поддержания кэшируемых объектов вручную в этой установке
  • Поддержка этого кода, когда схема DB изменяется, является большой проблемой.

Я ищу совет относительно того, что могло быть лучшей альтернативой для нас. Насколько я знаю, ORMs совершенствовался за прошлые 5 лет, таким образом, могло бы случиться так, что теперь существует тот, который предлагает приемлемую производительность. Поскольку я вижу эту проблему, мы должны обратиться к тем точкам:

  • Найдите некоторый способ снова использовать по крайней мере часть записанного SQL для выражения отображений
  • Имейте возможность выпустить собственные SQL-запросы без необходимости вручную анализировать их результаты (т.е. избегать руководства rs.getInt(42) поскольку они очень чувствительны к изменениям схемы),
  • Добавьте ненавязчивый слой кэширования
  • Следите за фигурами производительности.

Есть ли какая-либо платформа ORM, которую Вы могли рекомендовать относительно этого?

ОБНОВЛЕНИЕ Для предоставления чувства, какого вида из производительности полагает, что мы говорим о:

  • Базой данных бэкенда является TimesTen, база данных в оперативной памяти, которая работает на той же машине как JVM
  • Мы узнали то изменение rs.getInt("column1") кому: rs.getInt(42) приносит увеличение производительности, которое мы считаем значительными.
9
задан 4 revs 21 May 2010 в 09:56
поделиться

5 ответов

Вам действительно нужно переходить? Что заставляет вас переезжать? Есть ли здесь какая-то РЕАЛЬНАЯ необходимость или кто-то просто придумывает работу (архитектор-астронавт)?

Я согласен с ответами выше - если вам НУЖНО переходить - Hibernate или iBatis - хорошие варианты. iBatis особенно, если вы хотите оставаться "ближе" к SQL.

2
ответ дан 4 December 2019 в 13:00
поделиться

Если вам нужен стандартный уровень персистентности, позволяющий создавать собственные SQL-запросы, рассмотрите возможность использования iBATIS. Это довольно тонкое отображение между вашими объектами и SQL. http://ibatis.apache.org/

Для кэширования и "ленивых" объединений лучшим выбором может быть Hibernate. Я не использовал iBATIS для этих целей.

Hibernate обеспечивает большую гибкость, позволяя вам задавать определенные значения по умолчанию для ленивой загрузки по мере прохождения графа объектов, а также предварительно получать данные с помощью SQL или HQL-запросов, когда вам нужно лучшее время загрузки. Однако преобразование будет сложным для вас, поскольку оно имеет довольно высокую планку для входа с точки зрения обучения и настройки. Аннотации облегчили мне эту задачу.

Два преимущества перехода на стандартный фреймворк, о которых вы не упомянули: (1) поиск ошибок становится проще, когда у вас есть множество сайтов и форумов для поддержки. (2) нанимать новых сотрудников дешевле, проще и быстрее.

Удачи вам в решении проблем производительности и удобства использования. Компромиссы, на которые вы указываете, очень распространены. Извините, если я проповедовал.

5
ответ дан 4 December 2019 в 13:00
поделиться

Я недавно изучил кучу ORM для Java и не придумал ничего лучше Hibernate. Производительность Hibernate может помочь вам достичь поставленных целей.

Многие думают, что переход на Hibernate сделает все настолько крутым, но на самом деле это просто перенос набора проблем из запросов JDBC в настройку Hibernate. Прочтите кучу книг или (лучше) наймите «парня из спящего режима», чтобы тот пришел и помог.

Во время вашего рефакторинга я бы порекомендовал использовать JPA, чтобы вы могли отключить и повторно подключить нового поставщика сохраняемости, когда появится следующая большая проблема (или вы перейдете на Oracle)

3
ответ дан 4 December 2019 в 13:00
поделиться

Если вам нужно больше производительности: отбросьте базу данных (для работы в сети) и обработайте постоянство напрямую. Добавление кеширования не поможет вам с БД TimesTen, оно просто добавляет дополнительную копию (замедляет работу).

Возможно, вам стоит взглянуть на GemFire.

1
ответ дан 4 December 2019 в 13:00
поделиться

Для большинства ваших запросов я бы выбрал спящий режим. Он широко используется, хорошо документирован и в целом эффективен. Вы можете перейти к написанному вручную SQL, если спящий режим не производит достаточно эффективных запросов. Hibernate дает вам большой контроль при указании имен таблиц и столбцов, которым сопоставляются объекты домена, и в большинстве случаев вы можете приспособить его к существующей схеме.

  • Найдите способ повторно использовать хотя бы часть написанного SQL для выражения сопоставлений. Отображения выражаются в JPA с использованием аннотаций. Вы можете использовать существующий SQL в качестве руководства при создании запросов JPQL .

  • Добавьте ненавязчивый слой кэширования.

Кэширование в спящем режиме выполняется автоматически и прозрачно, если только вы специально не решите принять в нем участие.Вы можете пометить объекты как доступные только для чтения или исключить из кеша, контролировать, когда изменения сбрасываются в базу данных (конечно, внутри транзакции - автоматическое использование пакетной обработки повышает производительность, когда задержка в сети вызывает беспокойство).

  • Иметь возможность выпускать родной SQL-запросы без необходимости вручную разложить их результаты (т.е. избегайте ручного rs.getInt (42), поскольку они очень чувствительны к изменениям схемы)

Hibernate позволяет вам писать SQL и отображать его на ваши сущности. Вы не имеете дело с ResultSet напрямую - hibernate позаботится о деконструкции в вашу сущность. См. Глава 16, Собственный SQL в руководстве по гибернации.

  • Поддержка этого кода при изменении схемы БД - большая проблема.

Управление изменениями схемы все еще может быть проблемой, поскольку теперь у вас фактически есть две схемы - схема базы данных и сопоставление JPA (схема объекта). если вы решите позволить спящему режиму генерировать схему базы данных и перемещать в нее данные, вы больше не несете прямой ответственности за то, что попадает в базу данных, и тогда вы столкнетесь с необходимостью управления автоматическими изменениями в схеме, сгенерированной машиной. Есть инструменты, которые могут помочь, такие как dbmigrate и liquibase , но это не прогулка по парку. И наоборот, если вы управляете схемой db вручную, вам нужно будет тщательно переработать свои сущности, аннотации JPA и запросы, чтобы учесть изменения схемы.Добавление столбцов и новых сущностей относительно тривиально, но более сложные изменения, такие как изменение одного свойства на набор свойств или реструктуризация иерархии объектов, потребуют значительно более обширных изменений. Из этого нет простого выхода - либо db, либо hibernate являются «хозяином», который определяет схему, и когда один изменяется, другой должен следовать. Изменения кода не так уж и плохи - по моему опыту, перенос данных затруднен. Но это основная проблема с базами данных, и она будет присутствовать в любом решении, которое вы выберете.

Подводя итог, я бы перешел в спящий режим и использовал интерфейс JPA.

4
ответ дан 4 December 2019 в 13:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: