Hibernate, iBatis, Java EE или другой инструмент Java ORM
Мы планируем крупное корпоративное приложение. Мы фокусируем наши усилия на оценке спящего режима после переживания боли J2EE.
Похоже, что новый API Java EE проще. Я также прочитал некоторые хорошие вещи о Hibernate и iBatis. Наша команда имеет небольшой опыт работы с любыми структурами.
Есть 5 основных сравнительных точек, которые я бы хотел определить
- Есть ли веские причины не использовать ОРМ?
- Почему Hibernate не требует конструктора аргументов?
- Я обнаружил, что JPA, или, похоже, не поощряет шаблон DAO
- Entity Framework 4 vs NHibernate
- Dapper.Rainbow VS Dapper.Contrib
- Кривая обучения / простота использования
- производительность
- Сопровождаемость / Устойчивость
- Производительность / масштабируемость
- Простота поиска и устранения неисправностей
Если бы вам удалось создать команду из ~ 6 разработчиков с опытом J2EE, какой инструмент ORM вы бы использовали и почему?
- Разница между FetchType LAZY и EAGER в Java Persistence API?
- Как создать таблицу объединений с аннотациями JPA?
- Когда и почему сущности JPA должны реализовывать интерфейс Serializable?
- .net ORM Сравнение
- Указание индекса (не-уникальный ключ) с использованием JPA
- Пакетные вставки с JPA / EJB3
- Postgresql UUID поддерживается Hibernate?
- В чем разница между persist () и merge () в Hibernate?
Позвольте мне взломать это. Во-первых, я написал несколько статей по этому вопросу в разделе Использование ORM или простого SQL? , В частности, чтобы ответить на ваши вопросы:
Кривая обучения / простота использования
Ibatis – это SQL. Если вы знаете SQL, кривая обучения для ibatis тривиальна. Ibatis делает некоторые вещи поверх SQL, такие как:
- группа по;
- дискриминационные типы; а также
- динамический SQL.
что вам все равно нужно учиться, но самым большим препятствием является SQL.
JPA (включая Hibernate), с другой стороны, пытается дистанцироваться от SQL и представлять вещи в объекте, а не реляционным способом. Однако, как отмечает Джоэл, абстракции протекают, и JPA не является исключением. Чтобы сделать JPA, вам все равно нужно знать о реляционных моделях, SQL, настройке производительности запросов и т. Д.
В то время как Ibatis просто будет применять SQL, который вы знаете или учитесь, JPA потребует от вас узнать что-то еще: как его настроить (либо XML, либо annotations). Под этим я подразумеваю, что отношения внешнего ключа – это отношения (один-к-одному, один-ко-многим или многим-ко многим), тип-сопоставление и т. Д.
Если вы знаете 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 все еще повторяются, но я думаю, что это менее потенциальная проблема.
Однако это связано с ригидностью. Часто в приложении вам понадобятся биты и fragmentы данных из разных таблиц. С SQL это легко, потому что вы можете написать один запрос (или небольшое количество запросов), чтобы получить все эти данные за один удар и поместить его в пользовательский объект значения только для этой цели.
С JPA вы продвигаете эту логику в свой бизнес-уровень. Сущности в основном все или ничего. Теперь это не совсем так. Различные поставщики JPA позволят вам частично загружать объекты и т. Д., Но даже там вы говорите об одних и тех же дискретных активах. Если вам нужны данные из 4 таблиц, вам нужно либо 4 объекта, либо вам нужно объединить данные, которые вы хотите, в какой-то пользовательский объект значения на уровне бизнеса или презентации.
Еще одна вещь, которая мне нравится в ibatis, заключается в том, что весь ваш SQL является внешним (в файлах XML). Некоторые будут ссылаться на это как на недостаток, но не на меня. Затем вы можете легко найти использование таблицы и / или столбца, выполнив поиск в ваших XML-файлах. С SQL, встроенным в код (или где вообще нет SQL), это может быть намного сложнее найти. Вы также можете вырезать и вставлять SQL в инструмент базы данных и запускать его. Я не могу переоценить, сколько раз это было полезно для меня на протяжении многих лет.
Производительность / масштабируемость
Здесь я думаю, что ибатис побеждает. Это прямой SQL и низкая стоимость. По своей природе JPA просто не сможет управлять одним и тем же уровнем задержки или пропускной способности. Теперь, что делает JPA, это то, что латентность и пропускная способность – это лишь редкие проблемы. Высокопроизводительные системы, однако, существуют и будут склоняться к дисбалансу более тяжелых решений, таких как JPA.
Кроме того, с помощью ibatis вы можете написать запрос, который точно возвращает данные, которые вам нужны, с точными столбцами, которые вам нужны. По сути, JPA не может победить (или даже совпадение), когда он возвращает дискретные объекты.
Простота поиска и устранения неисправностей
Я думаю, что это тоже победа для Ибатиса. Как я уже упоминал выше, с JPA вы иногда будете тратить полдня на получение запроса или сущности, создающего SQL-запрос или диагностику проблемы, когда транзакция терпит неудачу, потому что диспетчер объектов пытался сохранить неуправляемый объект (который может быть частью пакета где вы совершили много работы, чтобы найти ее нетривиально).
Они оба потерпят неудачу, если вы попытаетесь использовать таблицу или столбец, которые не существуют, что хорошо.
Другие критерии
Теперь вы не отметили мобильность в качестве одного из ваших требований (что означает переход между поставщиками баз данных). Стоит отметить, что здесь JPA имеет преимущество. Аннотации менее переносимы, чем, скажем, Hibernate XML (например, стандартные annotations JPA не имеют эквивалента для «родного» ID типа Hibernate), но оба они более переносимы, чем ibatis / SQL.
Также я видел, что JPA / Hibernate используется как форма портативного DDL, то есть вы запускаете небольшую программу Java, которая создает схему базы данных из конфигурации JPA. С помощью ibatis вам понадобится скрипт для каждой поддерживаемой базы данных.
Недостатком переносимости является то, что JPA является, в некотором роде, самым низким общим знаменателем, что означает, что поддерживаемое поведение в основном является общим поддерживаемым поведением для широкого круга поставщиков баз данных. Если вы хотите использовать Oracle Analytics в ibatis, никаких проблем. В JPA? Ну, это проблема.
Простейшее эмпирическое правило между iBatis и Hibernate заключается в том, что если вам нужно больше SQL / реляционного представления о мире, iBatis лучше подходит; и для более сложной цепочки наследования и менее прямого представления SQL, Hibernate. Оба они широко используются и имеют прочную структуру. Поэтому я думаю, что оба они, вероятно, будут работать хорошо. Возможно, прочитайте учебник для обоих, посмотрите, звучит ли лучше, чем другой, и просто выберите его.
Из того, что вы перечисляете, я не думаю, что производительность очень различна – узкое место почти всегда будет базой данных, а не каркасом. Для других вещей, я думаю, что разные разработчики предпочли бы одно или другое, то есть нет общепринятого приоритета (для iBatis vs Hibernate).
Какое решение вы также используете, зависит от того, насколько вы согласны (или требуются) со спецификацией 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) даст вам больше головных болей, чем, может быть, стоит. Например:
- Если в базе данных нет первичных ключей кандидата (для эффективного hashCode & equals реализаций), вам нужно будет выполнить предварительный анализ, по которому столбцы определяют строку однозначно – возможно, просто, возможно, сложную в зависимости от сложности вашей схемы;
- Если вам не удастся добавить колонки версии или timestamp, вы теряете способность Hibernate делать оптимистичную блокировку и в конечном итоге должны запрашивать перед обновлением.
(Добавлено в ответ на первый комментарий) Если вам посчастливилось перепроектировать свою базу данных, два очень важных соображения, если вы собираетесь использовать ORM:
- Добавьте столбец номера версии во все соответствующие таблицы для поддержки оптимистической блокировки.
- Во время анализа данных выберите неэлементный столбец « альтернативного ключа », который разработчики должны использовать для
hashCode()
&equals()
. Не используйте столбцы PK в этих методах.
Чтобы добавить еще один вариант в список … посмотрите:
Ebean ORM ( http://ebean-orm.github.io ).
Основная претензия будет более простой, более интуитивной моделью программирования, чем JPA или Hibernate. В частности, у него нет сеанса Hibernate или JPA EntityManager, никаких отсоединенных / прикрепленных объектов (без слияния, сохранения, сброса), ленивая загрузка просто работает.
… ака гораздо проще использовать и понимать.
Вы также можете использовать свой собственный SQL-код с Ebean (для запросов, обновлений, хранимых процедур), а IMO – для соответствия требованиям Ibatis в использовании вашего собственного SQL.
Если вы хотите использовать ORM в Java SE, я предлагаю вам проверить это.
- Лицензия LGPL
- Используйте JPA-annotations для сопоставления (@Entity, @OneToMany и т. Д.)
- API без сеанса (без слияния, сохранения, сброса … save () и delete ())
- Поддержка «частичного объекта»
- Поддержка большого запроса (для контекста постоянной привязки объекта)
- Фоновые запросы
- Хорошая поддержка пакетной обработки
- Автоматическая настройка запросов (через «Автозапуск»)
Привет, Роб.
В настоящее время мы работаем над проектом, который использует как Hibernate, так и ibatis. Зачем использовать hibernate? Он поддерживает нашу модель домена, отношения и наследование. У нас довольно сложная модель домена, и hiberante очень хорошо ее поддерживает. Не нужно беспокоиться о вставках, обновлениях и т. Д. Ibatis используется только для просмотра. Есть запросы, и у нас есть объекты просмотра (похожие на модели домена, но не модели домена), которые сопоставляются с запросами. Ibatis возвращает данные в представлении obejct, которого вы хотите, не беспокоясь о чтении из набора результатов, которым вы должны управлять в Spring JDBC. Почему мы это вместо использования HQl или Spring JDBC? Домен настолько сложный, и при рендеринге мы выполняем вычисления, группируем по и множество собственных SQL-функций. мы делаем все это в запросе, используем динамические запросы, управляем условиями в ibatis и получаем чистый легкий объект. Имеет гораздо больший смысл, если вам нужно пересечь несколько слоев для извлечения данных в спящем режиме. Поэтому, в зависимости от вашей ситуации, вы можете использовать только один, оба или могут быть ничем. Но определенно, hibernate – это не то, с чем вы не можете жить.
Имейте в виду, что использование JPA / Hibernate (и, вероятно, большинства других решений ORM) в нетривиальных многопоточных приложениях может быстро стать реальной PITA, поскольку сеансы базы данных должны ограничиваться одним streamом (объекты сеанса не являются streamобезопасными). Добавьте ленивую загрузку и тот факт, что постоянные объекты могут принадлежать не более чем к одному активному сеансу … и вы входите в адскую поездку …
Возможно, вам захочется взглянуть на управление сеансом с помощью Hibernate в * многопоточном * Swing-приложении (или просто найти «hibernate multi-threaded»).
Мое эмпирическое правило (YMMV): Если приложение не поддается какому-либо циклу запроса / ответа (например, как веб-сервис), возможно, вам лучше использовать что-то еще.
Разумеется, другим решением было бы разработать приложение таким образом, чтобы обходить указанные ограничения инфраструктуры. Изменение дизайна приложения, чтобы я мог получить раму XYZ для работы, оставляет неприятное послевкусие.
Во всяком случае, только мои $ 0,02
Я думаю, что мы должны принять во внимание основную причину использования 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 должна быть для вашей модели, а не для Business Logic.
Query Query также не подходит для создания безопасных именных динамических запросов.
Если у вас действительно есть новый проект, вы можете использовать hibernate, но имейте в виду, что кривая обучения довольно крутая.
Если у вас есть существующая firebase database, вы намного лучше работаете с iBatis, потому что через один день вы будете продуктивны, и через два дня вы сможете узнать все об этом.
Одна вещь, которую вы должны учитывать, заключается в том, что критерии hibernate api отлично подходят для создания пользовательских запросов, которые в зависимости от вашего приложения могут быть хорошим аргументом для этого.
Если у вас нет хорошей объектной модели, я не вижу преимущества Hibernate. У вас, безусловно, есть «реляционная» в ORM, поскольку у вас есть реляционная firebase database, но «объект» является ключевым. Нет объектов, нет ORM. Я думаю, что сопоставление 1: 1 между объектами и таблицами, без более богатого поведения объекта, не оправдывает ORM. Придерживайтесь JDBC или iBatis, если это ваша ситуация.
Я бы посоветовал пойти с JPA и в зависимости (в значительной степени!) От продолжительности / объема вашего проекта вы могли бы также заглянуть в JPA2, поскольку он предоставляет некоторые из недостающих функций JPA (например, очень хороший API запросов).
Идите в hibernate. Ваш проект, безусловно, будет расти позже, и инвестиции (на обучение в hibernate) окупится так или иначе.
Вы пытались ответить, ПОЧЕМУ даже использовать инструмент ORM, прежде чем решить, какой из них использовать? Если у вас есть люди в вашей команде, которые знают SQL, посмотрите на JDBC.