Какую Java ORM вы предпочитаете и почему? [закрыто]


262

Это довольно открытый вопрос. Я начну новый проект и рассмотрю различные ORM для интеграции с доступом к базе данных.

У тебя есть любимые? Есть ли что-нибудь, что вы бы посоветовали держаться подальше?



Взгляните на микроформы - тонкие обертки вокруг технологии доступа к БД платформы - например, sql2o для Java github.com/aaberg/sql2o или ServiceStack.OrmLite для .NET github.com/ServiceStack/ServiceStack.OrmLite
tomaszkubacki

3
После более чем 5-летнего использования ORM мой личный выбор - Spring JDBC вместо ORM, и второе место - iBatis (MyBatis), мне не нравится спящий режим из-за кривой обучения, меньшего количества проблем с управлением и производительностью.

Вот (также закрытый) список облегченных jdbc-оболочек, которые можно использовать в качестве альтернативы полноформатным формам: stackoverflow.com/questions/7137929/…
Вадим

Ответы:


237

Я перестал использовать ORM.

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

Так что подумайте только об использовании пакета JDBC.


81
С ORM снова и снова повторяется одна и та же история: хорошая быстрая начальная разработка и дальнейшая трата ресурсов в проекте при отслеживании ошибок и недостатков, связанных с ORM. Я также ненавижу тот факт, что разработчикам кажется, что им никогда не приходится писать конкретные оптимизированные запросы.
Eelco

7
Эй, это все верно для больших реальных проектов?
santiagobasulto

30
Я согласен. Я использую ORM уже более 3 лет, и я не могу сказать, сколько времени было потрачено впустую (все еще остается) для решения проблем, связанных с постоянством. Мы не имеем никакого контроля над тем, что происходит «под капотом», конфигураций слишком много, чтобы управлять ими эффективно, и есть способы поведения, которые могут свести с ума. С другой стороны, у меня есть поддержка основных баз данных, и мне никогда не придется беспокоиться об их различиях.
Marcolopes

58
почему бы не использовать оба, в зависимости от сложности запроса / транзакции? это не так, как они взаимоисключающие.
амфибия

6
@WillSheppard да будет. Я использую Django ORM довольно часто, и он прекрасно работает. Я думаю, что разница может быть в динамической природе Python (и Perl). Использование ORM в Java - это боль. Но в динамических языках это может быть действительно выразительным. Есть несколько отличных проектов для встраивания операций ORM, таких как DSL в Python, и они великолепны.
santiagobasulto

97

Нет, потому что наличие ORM отнимает слишком много контроля с небольшими преимуществами. Полученная экономия времени легко сходит на нет, если вам необходимо отладить отклонения, возникающие в результате использования ORM. Кроме того, ORM не позволяют разработчикам изучать SQL и принципы работы реляционных баз данных и использовать их в своих интересах.


4
Я согласен с этим утверждением. Сколько из общего времени разработки будет потрачено на написание персистентного кода? Я думаю менее 10-15%
adrian.tarau

16
Это зависит. Конечно, если вы используете только один конкретный тип базы данных, легко обойтись без использования ORM. Однако, когда вам нужно поддерживать другие виды баз данных, они могут быстро стать менее управляемыми.
Джейсон Бейкер

3
«Экономия времени легко удаляется, когда приходится отлаживать отклонения, возникающие в результате использования ORM». Это не так, когда кривая навыков является приличным фактором при выборе технологий.
elsadek

7
Ваш аргумент может быть предложен против использования любой библиотеки. Наибольшую выгоду от ORM представляют такие вещи, как единицы работы, сопоставление объектов, отслеживание изменений, отложенная загрузка, миграции и взаимосвязи. Замечательно иметь возможность писать user.profile.givenName и не заботиться о том, какая структура использовалась для хранения данных для него.
Алекс

1
Он может быть использован против любой библиотеки, но в разной степени. Вообще я большой сторонник использования библиотек - зачем изобретать велосипед? Однако в этом случае я считаю, что Hibernate для большинства применений слишком тяжелый, и более легкий ORM будет более предпочтительным. Мой опыт основан на многолетнем опыте разработки с Hibernate и тщательного изучения его входов и выходов.
Симон

92

Многие ORM великолепны, вам нужно знать, почему вы хотите добавить абстракцию поверх JDBC. Я могу порекомендовать вам http://www.jooq.org (отказ от ответственности: я создатель jOOQ, поэтому этот ответ предвзят). JOOQ охватывает следующую парадигму:

  • SQL это хорошая вещь. Многие вещи могут быть выражены довольно хорошо в SQL. Нет необходимости в полной абстракции SQL.
  • Модель реляционных данных - это хорошо. Он доказал лучшую модель данных за последние 40 лет. Нет необходимости в базах данных XML или действительно объектно-ориентированных моделях данных. Вместо этого ваша компания использует несколько экземпляров Oracle, MySQL, MSSQL, DB2 или любой другой СУБД.
  • SQL имеет структуру и синтаксис. Это не должно быть выражено с использованием «низкоуровневой» конкатенации строк в JDBC - или «высокоуровневой» конкатенации строк в HQL - обе из них подвержены синтаксическим ошибкам.
  • Привязка к переменной имеет тенденцию быть очень сложной при работе с основными запросами. Это то, что должно быть абстрагировано.
  • POJO отлично подходят для написания кода Java, манипулирующего данными базы данных.
  • POJO - это боль писать и поддерживать вручную. Генерация кода это путь. Вы будете иметь безопасные для компиляции запросы, включая безопасность типов данных.
  • База данных на первом месте. Хотя приложение поверх вашей базы данных может со временем меняться, сама база данных, вероятно, будет работать дольше.
  • Да, у вас есть хранимые процедуры и пользовательские типы (UDT) в вашей устаревшей базе данных. Ваша база данных должна поддерживать это.

Есть много других хороших ORM. Особенно Hibernate или iBATIS имеют отличное сообщество. Но если вы ищете интуитивный, простой, я скажу попробовать JOOQ. Тебе это понравится! :-)

Проверьте этот пример SQL:

  // Select authors with books that are sold out
  SELECT * 
    FROM T_AUTHOR a
   WHERE EXISTS (SELECT 1
                   FROM T_BOOK
                  WHERE T_BOOK.STATUS = 'SOLD OUT'
                    AND T_BOOK.AUTHOR_ID = a.ID);

И как это можно выразить в jOOQ:

  // Alias the author table
  TAuthor a = T_AUTHOR.as("a");

  // Use the aliased table in the select statement
  create.selectFrom(a)
        .whereExists(create.selectOne()
                           .from(T_BOOK)
                           .where(T_BOOK.STATUS.equal(TBookStatus.SOLD_OUT)
                           .and(T_BOOK.AUTHOR_ID.equal(a.ID))))));

1
Инструменты ORM настолько хороши, насколько вам удается правильно их использовать. Есть проекты, в которых инструменты ORM работают как брелоки, в то время как в других они совсем не подходят. В конце концов, ответственность за выбор правильного инструмента для требований проекта лежит на команде разработчиков. Инструменты ORM сложны. К сожалению, только часть всех разработчиков потратит время, чтобы понять, как они работают. Остальные просто обвинят инструмент и скажут, что он плохой. Вопрос в том, дает ли самый голосующий ответ лучший совет? > Так что рассмотрите возможность использования пакета JDBC. Мы действительно хотим использовать простой JDBC?
Влад Михальча

Я стараюсь не пускать «База данных на первом месте». Приложение содержит бизнес-правила для функций, запрашиваемых клиентом, и они почти никогда не просят создать базу данных. Это техническая деталь, определенная во время реализации.
Квеббл

58

Hibernate, потому что это в основном стандарт де-факто в Java и был одной из движущих сил в создании JPA. Он получил отличную поддержку в Spring, и почти каждая инфраструктура Java поддерживает его. Наконец, GORM - это действительно классная оболочка, которая делает динамические поиски и так далее, используя Groovy.

Он даже был портирован на .NET (NHibernate), так что вы также можете использовать его там.


4
Я голосую Hib тоже, но с важным дополнением: мы должны использовать JPA API только даже если реализация JPA является фактически предоставленной Hib.
Владимир Дюжев

52

Спящий, потому что это:

  • Стабильно - находясь рядом столько лет, ему не хватает серьезных проблем.
  • диктует стандарты в области ORM
  • реализует стандарт (JPA), в дополнение к его диктовке.
  • имеет тонны информации об этом в Интернете. Есть много учебных пособий, общих решений проблем и т. Д.
  • является мощным - вы можете перевести очень сложную объектную модель в реляционную модель.
  • он поддерживает любые основные и средние СУБД
  • с ним легко работать, если вы хорошо его освоите

Несколько моментов о том, почему (и когда) использовать ORM:

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

Когда я сравниваю Hibernate и JPA, я выбираю Hibernate, а если сравниваю JPA и JDO, я выбираю JDO! Мне очень нравится JDO, но мне нравятся две функции Hibernate (которые недоступны в JDO), одна из них - @Filters, а другая - вы можете отобразить поля версии (для оптимистической блокировки) в обычные поля, что невозможно в JDO ,
Амир Пашазаде

27

Я бы порекомендовал использовать MyBatis . Это тонкий слой поверх JDBC, очень легко отображать объекты в таблицы и при этом использовать простой SQL, все находится под вашим контролем.


10
Ibatis для сложных операций чтения и Hibernate для создания, обновления, удаления и простых операций чтения - идеальный выбор.
Дарп

19

У меня был действительно хороший опыт работы с Avaje Ebean когда я писал приложение JavaSE среднего размера.

Он использует стандартные аннотации JPA для определения сущностей, но предоставляет гораздо более простой API (без EntityManager или какой-либо другой хрени с присоединенными / отсоединенными сущностями). Это также позволяет вам легко использовать SQL-запросы или простые JDBC-вызовы при необходимости.

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

List<Person> boys = Ebean.find(Person.class)
                                  .where()
                                       .eq("gender", "M")
                                       .le("age", 18)
                                  .orderBy("firstName")
                                  .findList();

6
Я должен быть немного странным ... выберите из Персона, где пол = 'M' и возраст <18, заказанный firstName, выглядит для меня намного лучше :-)
Eelco

4
Это одна из лучших форм, которые я видел в Java. Решение об использовании синглтона является освежающим и дает ему огромное практическое преимущество перед другими.
opsb

Я думаю, вы имеете в виду беглый, а не текучий
Montdidier

@opsb Я думаю, технически это моностат, а не синглтон.
Montdidier

Как начать работу с Avaje Ebean ORM? Любые видео уроки?
Авинаш

11

SimpleORM , потому что это просто и без магии. Он определяет все структуры метаданных в коде Java и является очень гибким.

SimpleORM предоставляет функциональность, аналогичную Hibernate, путем сопоставления данных в реляционной базе данных с объектами Java в памяти. Запросы могут быть заданы в терминах объектов Java, идентичность объекта совпадает с ключами базы данных, отношения между объектами поддерживаются, а измененные объекты автоматически сбрасываются в базу данных с оптимистическими блокировками.

Но, в отличие от Hibernate, SimpleORM использует очень простую объектную структуру и архитектуру, которая позволяет избежать необходимости сложного анализа, обработки байтового кода и т. Д. SimpleORM является небольшим и прозрачным, упакован в две банки размером всего 79 КБ и 52 КБ, с одной маленькой и опциональной зависимость (Slf4j). (Hibernate более 2400K плюс около 2000K зависимых JAR-файлов.) Это упрощает понимание SimpleORM и значительно снижает технический риск.


Не использовал его, но ActiveObjects описывает себя как своего рода Hibernate-lite на своем веб-сайте, поэтому, вероятно, есть некоторое сходство.
Абдулла Джибали

10

Eclipse Link , по многим причинам, но особенно я чувствую, что у него меньше вздутия, чем у других решений основного потока (по крайней мере, меньше вздутие живота)

Ох, и Eclipse Link была выбрана в качестве эталонной реализации для JPA 2.0


5

Хотя я разделяю озабоченность по поводу замены Java для запросов SQL в свободной форме, я действительно думаю, что люди, критикующие ORM, делают это из-за в целом плохого дизайна приложений.

Истинный OOD определяется классами и отношениями, а ORM обеспечивает согласованное отображение различных типов отношений и объектов. Если вы используете инструмент ORM и в конечном итоге кодируете выражения запросов на любом языке запросов, поддерживаемом платформой ORM (включая, помимо прочего, деревья выражений Java, методы запросов, OQL и т. Д.), Вы определенно делаете что-то неправильно, то есть модель вашего класса. скорее всего, не поддерживает ваши требования так, как должно. Чистый дизайн приложения на самом деле не требует запросов на уровне приложения. Я проводил рефакторинг многих проектов, которые люди начинали использовать ORM-фреймворк так же, как они использовались для встраивания строковых констант SQL в их код, и в итоге все были удивлены тем, насколько простым и понятным становится все приложение, когда вы соответствуете до модели вашего класса с моделью использования. Конечно, для таких вещей, как функциональность поиска и т. Д. Вам нужен язык запросов, но даже в этом случае запросы настолько ограничены, что создание даже сложного VIEW и отображение его на постоянный класс, доступный только для чтения, гораздо приятнее поддерживать и смотреть, чем создавать выражения на некотором языке запросов в коде вашего приложения. Подход VIEW также использует возможности базы данных и, благодаря материализации, может быть намного лучше с точки зрения производительности, чем любой рукописный SQL в вашем источнике Java. Таким образом, я не вижу никакой причины для нетривиального приложения НЕ использовать ORM. но даже в этом случае запросы настолько ограничены, что создание даже сложного VIEW и отображение его на постоянный класс, доступный только для чтения, гораздо приятнее в обслуживании и взгляде, чем построение выражений на каком-либо языке запросов в коде вашего приложения. Подход VIEW также использует возможности базы данных и, благодаря материализации, может быть намного лучше с точки зрения производительности, чем любой рукописный SQL в вашем источнике Java. Таким образом, я не вижу никакой причины для нетривиального приложения НЕ использовать ORM. но даже в этом случае запросы настолько ограничены, что создание даже сложного VIEW и отображение его на постоянный класс, доступный только для чтения, гораздо приятнее в обслуживании и взгляде, чем построение выражений на каком-либо языке запросов в коде вашего приложения. Подход VIEW также использует возможности базы данных и, благодаря материализации, может быть намного лучше с точки зрения производительности, чем любой рукописный SQL в вашем источнике Java. Таким образом, я не вижу никакой причины для нетривиального приложения НЕ использовать ORM.


11
Если вы создаете приложения поверх постоянного хранилища, как это делают многие из нас, будь то СУБД или разновидность NoSQL, у этого хранилища будет собственный эффективный способ доступа к нему. Попытка абстрагироваться от этого - это просто перегрузка. Чрезмерное усердие в отношении «истинного OOD» позволяет получить те архитектуры астронавтов, которыми славится Java.
Eelco
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.