Hibernate, iBatis, Java EE или другой инструмент Java ORM - PullRequest
65 голосов
/ 04 апреля 2009

Мы находимся в процессе планирования большого корпоративного приложения. Мы сосредотачиваем наши усилия на оценке гибернации после переживаний J2EE.

Похоже, новый API Java EE стал проще. Я также прочитал некоторые хорошие вещи о Hibernate и iBatis. Наша команда имеет небольшой опыт работы с любым из фреймворков.

Есть 5 основных точек сравнения, которые я бы хотел определить

  • Кривая обучения / простота использования
  • Производительность
  • ремонтопригодность / Стабильность
  • Производительность / масштабируемость
  • Простота устранения неисправностей

Если бы вы руководили командой из ~ 6 разработчиков с опытом работы с J2EE, какой инструмент ORM вы бы использовали и почему?

Ответы [ 12 ]

111 голосов
/ 04 апреля 2009

Позвольте мне разобраться с этим. Во-первых, я написал несколько статей на эту тему в Использование ORM или простого SQL? . Специально для решения ваших пунктов:

Кривая обучения / простота использования

Ибатис о SQL. Если вы знаете SQL, кривая обучения для ibatis тривиальна. Ibatis делает некоторые вещи поверх SQL, такие как:

  • сгруппировать по;
  • различимые типы; и
  • динамический SQL.

, что вам все еще нужно учиться, но самым большим препятствием является SQL.

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

В то время как Ibatis просто попросит вас применить SQL, который вы знаете или изучаете, JPA потребует, чтобы вы знали кое-что еще: как его настроить (либо XML, либо аннотации). Под этим я подразумеваю выяснение того, что отношения внешнего ключа - это отношения (один-к-одному, один-ко-многим или многие-ко-многим), сопоставление типов и т. Д.

Если вы знаете SQL, я бы сказал, что барьер для изучения JPA на самом деле выше. Если вы этого не сделаете, это скорее смешанный результат с JPA, позволяющий вам на некоторое время эффективно отложить изучение SQL (но это не откладывает на неопределенное время).

С JPA, как только вы настроите свои сущности и их отношения, тогда другие разработчики могут просто использовать их, и им не нужно узнавать все о настройке JPA. Это может быть преимуществом, но разработчику все равно нужно знать о менеджерах сущностей, управлении транзакциями, управляемых и неуправляемых объектах и ​​т. Д.

Стоит отметить, что JPA также имеет свой собственный язык запросов (JPA-SQL), который вам нужно будет узнать, знаете ли вы SQL. Вы найдете ситуации, когда JPA-SQL просто не может делать то, что может SQL.

Производительность

Об этом сложно судить. Лично я думаю, что я более продуктивен в ibatis, но я также очень доволен SQL. Некоторые утверждают, что они более продуктивны с Hibernate, но, возможно, это связано, по крайней мере частично, с незнанием SQL.

Также производительность с JPA обманчива, потому что вы иногда сталкиваетесь с проблемой с вашей моделью данных или запросами, которая занимает у вас от полдня до дня, чтобы решить, когда вы включаете ведение журнала и смотрите, какой SQL производит ваш JPA-провайдер. а затем вырабатываете комбинацию настроек и вызовов, чтобы получить что-то правильное и производительное.

У вас просто нет такой проблемы с Ibatis, потому что вы сами написали SQL. Вы можете проверить это, запустив SQL в PL / SQL Developer, SQL Server Management Studio, Navicat для MySQL или что-то еще. После того, как запрос верен, все, что вы делаете, это отображаете входы и выходы.

Также я обнаружил, что JPA-QL более неуклюжий, чем чистый SQL. Вам нужны отдельные инструменты, чтобы просто выполнить запрос JPA-QL, чтобы увидеть результаты, и это то, что вы должны изучить. Я действительно нашел всю эту часть JPA довольно неловкой и громоздкой, хотя некоторым это нравится.

ремонтопригодность / Стабильность

Опасность Ibatis в этом случае заключается в том, что ваша команда разработчиков может просто продолжать добавлять объекты-значения и запросы по мере необходимости, вместо того, чтобы искать повторное использование, в то время как JPA имеет одно право на таблицу, и как только вы получите эту сущность, вот и все. Именованные запросы имеют тенденцию идти к этой сущности, поэтому их трудно пропустить. Специальные запросы все еще могут повторяться, но я думаю, что это меньше потенциальной проблемы.

Однако это происходит за счет жесткости. Часто в приложении вам нужны кусочки данных из разных таблиц. С SQL это легко, потому что вы можете написать один запрос (или небольшое количество запросов), чтобы получить все эти данные одним ударом и поместить их в объект пользовательского значения только для этой цели.

С JPA вы продвигаете эту логику в свой бизнес-уровень. Сущности в основном все или ничего. Теперь это не совсем верно. Различные провайдеры JPA позволят вам частично загружать сущности и т. Д., Но даже там вы говорите об одних и тех же отдельных правах. Если вам нужны данные из 4 таблиц, вам нужно либо 4 объекта, либо вам нужно объединить нужные данные в какой-то объект настраиваемого значения на бизнес-уровне или уровне представления.

Еще одна вещь, которая мне нравится в ibatis, это то, что весь ваш SQL является внешним (в файлах XML). Некоторые будут ссылаться на это как недостаток, но не я. Затем вы можете относительно легко найти использование таблицы и / или столбца, выполнив поиск по вашим XML-файлам. С SQL, встроенным в код (или там, где вообще нет SQL), его может быть намного сложнее найти. Вы также можете вырезать и вставлять SQL в инструмент базы данных и запускать его. Я не могу переоценить, сколько раз это было полезно для меня за эти годы.

Производительность / масштабируемость

Здесь я думаю, что Ибатис побеждает. Это прямой SQL и низкая стоимость. По своей природе JPA просто не сможет управлять одинаковым уровнем задержки или пропускной способности. Теперь JPA стремится к тому, чтобы задержки и пропускная способность возникали редко. Высокопроизводительные системы, тем не менее, существуют и будут иметь тенденцию отказываться от более тяжелых решений, таких как JPA.

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

Простота устранения неисправностей

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

Они оба потерпят неудачу, если вы попытаетесь использовать несуществующую таблицу или столбец, что хорошо.

Другие критерии

Теперь вы не упомянули переносимость как одно из ваших требований (имеется в виду перемещение между поставщиками баз данных). Стоит отметить, что здесь JPA имеет преимущество. Аннотации менее переносимы, чем, скажем, Hibernate XML (например, стандартные аннотации JPA не имеют эквивалента для «родного» идентификатора Hibernate), но обе они более переносимы, чем ibatis / SQL.

Также я видел JPA / Hibernate, используемый в качестве формы переносимого DDL, что означает, что вы запускаете небольшую Java-программу, которая создает схему базы данных из конфигурации JPA. С ibatis вам потребуется скрипт для каждой поддерживаемой базы данных.

Недостатком переносимости является то, что JPA является, в некотором смысле, наименьшим общим знаменателем, что означает, что поддерживаемое поведение является в основном распространенным поддерживаемым поведением для широкого круга поставщиков баз данных. Если вы хотите использовать Oracle Analytics в ibatis, нет проблем. В JPA? Ну, это проблема.

11 голосов
/ 04 апреля 2009

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

Что вы перечислите, я не думаю, что производительность сильно отличается - узким местом почти всегда будет база данных, а не фреймворк. Для других вещей я думаю, что разные разработчики предпочтут один или другой, то есть нет общепринятого приоритета (для iBatis против Hibernate).

7 голосов
/ 06 апреля 2009

Решение, с которым вы работаете, также зависит от того, насколько вы согласны (или необходимы) со спецификацией Java EE. JPA является «стандартом» для доступа к данным в системах Java EE, поэтому, если вы особенно строго придерживаетесь этого, вам следует использовать его (с некоторыми оговорками).

JPA - это стандартизация систем объектно-реляционного отображения. Как таковой, он не обеспечивает реализацию, он просто определяет стандартизированный подход. Hibernate Entity Manager - одна из таких реализаций.

Поскольку JPA является стандартом для нескольких поставщиков и все еще является довольно новым, в нем отсутствуют некоторые более эзотерические функции, которые могут быть полезны в некоторых случаях использования (например, API Criteria для генерации динамического SQL). Если вы используете план JPA в ситуациях, когда вам необходимо использовать Hibernate напрямую или даже JDBC напрямую. Для таких ситуаций очень полезен общий шаблон DAO; Вы можете изменить это: Универсальные объекты доступа к данным для использования в JPA & JDBC довольно легко.

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

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

Наконец, если у вас есть устаревшая модель данных, с которой у вас мало гибкости, Hibernate (и JPA) доставит вам больше головной боли, чем, возможно, стоит. Например:

  • Если база данных не имеет возможных первичных ключей (для эффективных реализаций hashCode & equals), вам нужно будет выполнить предварительный анализ того, какие столбцы определяют строку однозначно - возможно, просто, а возможно, сложно в зависимости от сложности вашей схемы;
  • Если вы не можете добавить столбцы версии или метки времени, вы теряете способность Hibernate делать оптимистическую блокировку и в конечном итоге вынуждены выполнять запросы перед обновлением.

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

  • Добавить столбец номера версии во все соответствующие таблицы для поддержки оптимистической блокировки.
  • Во время анализа данных выберите необнуляемые столбцы " альтернативный ключ ". что разработчики должны использовать для hashCode() & equals(). Не используйте колонки PK в тех методы.
6 голосов
/ 11 ноября 2009

Чтобы добавить еще один вариант в список ... взгляните на:

Eese ORM (http://ebean -orm.github.io ).

Это главное утверждение - более простая и интуитивно понятная модель программирования, чем JPA или Hibernate. В частности, у него нет Hibernate Session или JPA EntityManager, нет отделенных / прикрепленных объектов (без слияния, сохранения, сброса), ленивая загрузка просто работает.

... намного проще в использовании и понимании.

Вы также можете использовать свой собственный SQL с Ebean (для запросов, обновлений, хранимых процедур), и IMO соответствует Ibatis по простоте использования по сравнению с вашим собственным SQL.

Если вы хотите использовать ORM в Java SE, я бы посоветовал вам проверить его.

  • Лицензия LGPL
  • Использовать аннотации JPA для сопоставления (@Entity, @OneToMany и т. Д.)
  • API без сессий (без слияния, сохранения, сброса ... save () и delete ())
  • Поддержка "Частичных объектов"
  • Поддержка больших запросов (для контекста персистентности графа объекта)
  • Фоновые запросы
  • Хорошая поддержка для пакетной обработки
  • Автоматическая настройка запросов (через «Автозагрузку»)

Ура, Роб.

5 голосов
/ 13 сентября 2011

В настоящее время мы работаем над проектом, который использует Hibernate и ibatis. Зачем использовать спящий режим? Он поддерживает нашу модель предметной области, отношений и наследования. У нас довольно сложная модель предметной области, и hiberante очень хорошо ее поддерживает. Не нужно беспокоиться о написании вставок, обновлений и т. Д. Ибатис используется только для просмотра. Есть запросы, и у нас есть объекты представления (похожие на доменные модели, но не доменные модели), которые сопоставляются с запросами. Ibatis возвращает данные в нужном объекте представления, не беспокоясь о чтении из набора результатов, которым вы должны управлять в Spring JDBC. Почему мы вместо этого используем HQl или Spring JDBC? Домен настолько сложен, и при рендеринге мы выполняем вычисления, группируясь по множеству собственных функций SQL. мы делаем все это в запросе, используем динамические запросы, управляем условиями в ibatis и получаем чистый легкий объект. Имеет больше смысла, если вам нужно пройти несколько слоев, чтобы получить данные в спящем режиме Таким образом, в зависимости от вашей ситуации, вы можете использовать только один, оба или не использовать ни один. Но, безусловно, гибернация - это не то, без чего вы не можете жить.

4 голосов
/ 24 мая 2012

Я думаю, что мы должны принять во внимание основную причину, по которой мы используем Java (или OO).

Система должна быть гибкой и позволять постоянно изменять спецификации (это часто случается в реальной жизни). В противном случае мы должны были программировать на C, потому что это намного быстрее.

Я думаю, что лучшим стеком для веб-приложений была бы Java EE: JPA - EJB - JSF (с расширенной областью контекстной беседы с постоянством).

JSF также медленнее, чем чистый JSP / Servlet, но быстрее разрабатывается.

JPA сложнее в освоении, но быстрее в разработке (вы знаете: RAD), и изменения не имеют большого значения (подвержена ошибкам копия -паста) воздействие. Добавьте новый столбец в наиболее часто используемую сущность, и вам придется обновить все операторы в iBatis ...

JPA не очень хорошо работает во всех случаях, но охватывает большинство из них, а также Позвольте вам подключить Native Query вместо JPQL без изменения кода. Но если вы обнаружите, что пишете слишком много Native Query, ваш проект может подойти лучше iBatis

А что касается производительности, JPA также эффективен, если вы понимаете, как все переводится на SQL, и если вы заставляете его делать то, что у него получается лучше всего, если вы заставляете его делать то, что ему неудобно, это будет генерировать слишком много запросов. Там нет магии! Вы должны быть осведомлены о сгенерированном запросе и не должны вслепую надеяться, что вы сможете выбрать легкий путь, когда может появиться какой-то сложный случай.

Также, если разработчики обладают всеми возможностями SQL, они будут писать слишком сложные запросы для обработки бизнес-логики, вместо того, чтобы располагать ее централизованно, у вас будет некоторая бизнес-логика в SQL, а некоторые в EJB. JPA должен быть для сохранения вашей модели, а не для бизнес-логики.

Критерий Query также не подходит для создания безопасных динамических запросов nomatterhowcomplex.

4 голосов
/ 14 января 2010

Имейте в виду, что использование JPA / Hibernate (и, возможно, большинства других решений ORM) в нетривиальных многопоточных приложениях может быстро стать настоящим PITA, поскольку сеансы базы данных должны быть ограничены ровно одним потоком (объекты сеанса не являются потоковыми безопасный). Добавьте ленивую загрузку и тот факт, что персистентные сущности могут принадлежать не более чем одному активному сеансу ... и вас ждет адская поездка ...

Возможно, вы захотите взглянуть на Управление сессиями с помощью Hibernate в * многопоточном * Swing-приложении (или просто поискать «многопоточный hibernate»).

Мое эмпирическое правило (YMMV): если приложение не поддается какому-либо циклу запроса / ответа (например, веб-сервис), вам, вероятно, будет лучше использовать что-то другое.

Конечно, другим решением было бы разработать приложение таким образом, чтобы обойти упомянутые ограничения платформы. Изменение дизайна приложения, чтобы я мог заставить работать фреймворк XYZ, оставляет плохое послевкусие.

В любом случае, только мои $ 0,02

3 голосов
/ 08 июня 2009

Если у вас действительно есть проект с нуля, вы можете использовать спящий режим, но имейте в виду, что кривая обучения довольно крутая.

Если у вас есть существующая база данных, с iBatis вам гораздо лучше, потому что через один день вы будете продуктивны, а через два дня вы сможете узнать все об этом.

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

2 голосов
/ 06 апреля 2009

Я бы посоветовал перейти с JPA и, в зависимости (в значительной степени!) От продолжительности / объема вашего проекта, вы также можете посмотреть на JPA2, поскольку он предоставляет некоторые из отсутствующих функций JPA (например, очень хороший API запросов) ).

2 голосов
/ 04 апреля 2009

Если у вас нет хорошей объектной модели, я не вижу преимущества Hibernate. У вас определенно есть «реляционный» в ORM, так как у вас есть реляционная база данных, но «объект» является ключевым. Нет объектов, нет ORM. Я думаю, что отображение 1: 1 между объектами и таблицами, без более богатого поведения объекта, не оправдывает ORM. Придерживайтесь JDBC или iBatis, если это ваша ситуация.

...