JPA зачем использовать createNamedQuery

Я участвую в процессах изменения уровня DAO с помощью Hibernate API на использование чистой реализации JPA API. Похоже, что рекомендуемый метод - использовать createNamedQuery из диспетчера сущностей. Именованные запросы хранятся в аннотациях в классах model/entity. Это просто не имеет смысла для меня. Почему вы определяете запросы JPA в объектах модели, но используете их в DAO. Разве не имеет смысла просто использовать createQuery из самого DAO и определять запросы в DAO или даже просто определять именованные запросы в самом DAO?

Для тех из вас, кто реализовал ваш уровень DAO с помощью API JPA, как вы определили свои запросы?

Ответы

Ответ 1

Я использую именованные запросы.

Для этого есть две причины:

  • Он ставит их в более центральное место, а не разбросано по коду со случайными вызовами createQuery(); и
  • Процессы сборки могут проверять запросы (действительно полезны).

Ответ 2

Вы можете взглянуть на Spring Data JPA. Это позволяет вам просто определить интерфейс и выполнить запросы без необходимости выполнения выполнения вручную.

Entity:

@Entity
@NamedQuery(id="User.findByLastname" query="from User u where u.lastname = ?1")
public class User implements Persistable<Long> {

  @Id
  private Long id;
  private String username;
  private String lastname;
  private int age;
}

Repository:

public interface UserRepository extends CrudRepository<User, Long> {

  // Will trigger the NamedQuery due to a naming convention
  List<User> findByLastname(String lastname);

  // Will create a query from the methodname
  // from User u where u.username = ?
  User findByUsername(String username);

  // Uses query annotated to the finder method in case you
  // don't want to pollute entity with query info
  @Query("from User u where u.age > ?1")
  List<User> findByAgeGreaterThan(int age);
}

Настройка:

EntityManager em = Persistence.getEntityManagerFactory().createEntityManager();
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);

UserRepository repository = factory.getRepository(UserRepository.class);

Как вы видите, вы можете выбирать между различными способами получения запроса, который должен быть выполнен из метода. Хотя получение его непосредственно из имени метода возможно для простых запросов, которые вы, вероятно, выбираете между стандартом @NamedQuery (стандарт JPA) или @Query (Spring аннотацией данных JPA), зависящим от того, насколько вы предпочитаете придерживаться стандартов.

Spring Data JPA предоставляет вам поддержку в различных других областях реализации уровня доступа к данным, позволяет предоставлять пользовательские реализации для методов и прекрасно интегрируется с Spring.

Ответ 3

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

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

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

Ответ 4

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

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

[Обновление]

Вместо этого вы можете записать именованные запросы при сопоставлении.

Ответ 5

Объявите силу и:) Если у вас есть запрос, который имеет смысл помещать в модель, сделайте это. Если вы этого не сделаете, не делайте этого. Может быть, даже лучше спросить: "Почему вы пишете DAO с JPS?" Если ответ "Изолировать мой код из базы данных". Это осуществляется библиотекой, реализующей JPA. Если ответ "изолировать мой код от изменений в том, как я сохраняю вещи", то JPA делает это, позволяя вам иметь разные реализации. Я использую объекты запросов для сложных запросов и по-прежнему использую именованные запросы, и мне нравится тот факт, что именованные запросы компилируются, и поэтому я обнаружил ошибки в них намного быстрее. У меня нет слоя DAO.