Полезно ли использовать @NamedQuery для выбора одного столбца (J2EE / JPA, Hibernate) - PullRequest
3 голосов
/ 31 октября 2011

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

In the Entity:
@NamedQueries({
@NamedQuery(name = "DealRaw.findByrawUrl", query = "SELECT d FROM DealRaw d WHERE d.rawUrl = :rawUrl"),
@NamedQuery(name = "DealRaw.findByState", query = "SELECT d FROM DealRaw d WHERE d.state = :state"),
.... etc ....
})

, а затем

In the Service Class
Query qR=_em.createNamedQuery("DealRaw.findByrawUrl");  //_em is an EntityManager
qR.setParameter("rawUrl", value);
List<DealRaw> dRs=(List <DealRaw>)qR.getResultList();

Ответы [ 3 ]

2 голосов
/ 31 октября 2011

Это не SQL-запросы, а JPQL-запросы.И вы можете поместить любой запрос в именованный запрос, сложный или нет.

Все они имеют одинаковые преимущества:

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

Все они имеют одинаковый недостаток, IMO: запрос не определенгде он используется, и поэтому код сложнее понять.

Независимо от того, названы ли эти запросы или нет, вам придется написать эти запросы для их выполнения.Единственные другие способы загрузки объектов - это найти их, используя их идентификатор (что здесь не так), или перейти от одного объекта к другому, используя ассоциации (что не так).

1 голос
/ 31 октября 2011

Как сказал Дж. Б. Низет, чтобы найти набор результатов, вам нужно где-то написать запросы.

Одним из преимуществ использования их в качестве NamedQuery (или CriteriaQuery, если это ваша вещь) является то, что вы защищаете себя от внедрения SQL. Если запрос создается на лету в коде с конкатенацией строк, например String query = "SELECT d FROM DealRaw d WHERE d.rawUrl = '" + rawUrl + "'";, или даже с использованием именованных параметров, некоторые программисты в будущем могут прийти и изменить запрос таким образом, который позволяет внедрять SQL (как в примере) .

Да, есть способы использовать именованные параметры в запросе, построенном в коде с конкатенацией, но это не защищает вас так сильно, как предопределенный Именованный запрос.

1 голос
/ 31 октября 2011

Почему бы не использовать Критерии вместо NamedQuery?Фильтрация будет намного проще.В некоторых случаях создание критериев становится очень запутанным и сложным, однако для одного столбца я считаю, что это самый простой вариант.

...