Hibernate, iBatis, Java EE или другой инструмент Java ORM

Мы планируем большое корпоративное приложение. Мы фокусируем наши усилия на оценке спящего режима после того, как испытываем боли J2EE.

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

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

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

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

Ответ 1

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

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

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

  • group by;
  • дискриминированные типы; и
  • динамический 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 имеет одно право на каждую таблицу и после того, как у вас есть этот объект. Именованные запросы, как правило, идут на эту сущность, поэтому их трудно пропустить. Запросы ad-hoc все еще повторяются, но я думаю, что это менее потенциальная проблема.

Однако это связано с ригидностью. Часто в приложении вам понадобятся биты и фрагменты данных из разных таблиц. С 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 вам понадобится script для каждой поддерживаемой базы данных.

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

Ответ 2

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

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

Ответ 3

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

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

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

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

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

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

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

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

Ответ 4

Чтобы добавить еще один вариант в список... посмотрите:

Ebean ORM (www.avaje.org).

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

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

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

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

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

Приветствия, Роб.

Ответ 5

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

Ответ 6

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

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

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

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

Во всяком случае, только мои $0.02

Ответ 7

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

Ответ 8

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

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

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

Ответ 9

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

Ответ 10

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

Ответ 11

Перейдите в спящий режим. Ваш проект, безусловно, будет расти позже, и инвестиции (при обучении в спящий режим) так или иначе окупится.

Ответ 12

Вы пытались ответить ПОЧЕМУ даже использовать инструмент ORM, прежде чем решать, какой из них использовать? Если у вас есть люди в вашей команде, которые знают SQL, посмотрите на JDBC.