Ответ
Да, JPA предоставляет несколько механизмов для написания запросов:
1. JPQL (Java Persistence Query Language)
Объектно-ориентированный язык запросов, похожий на SQL, но работающий с сущностями.
TypedQuery<User> query = em.createQuery(
"SELECT u FROM User u WHERE u.age > :minAge", User.class
);
query.setParameter("minAge", 18);
List<User> users = query.getResultList();
2. Нативные SQL-запросы (Native Queries)
Используются для сложных запросов или специфичных для СУБД функций.
Query query = em.createNativeQuery(
"SELECT * FROM users WHERE registration_date > ?", User.class
);
query.setParameter(1, startDate);
List<User> users = query.getResultList();
3. Criteria API
Типобезопасный и динамический способ построения запросов через Java API.
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> user = cq.from(User.class);
cq.select(user).where(cb.gt(user.get("age"), 18));
List<User> users = em.createQuery(cq).getResultList();
4. Именованные запросы (Named Queries)
Предопределенные запросы, объявляемые с помощью аннотации @NamedQuery прямо в классе сущности.
@Entity
@NamedQuery(name = "User.findByStatus",
query = "SELECT u FROM User u WHERE u.status = :status")
public class User { ... }
// Использование
List<User> users = em.createNamedQuery("User.findByStatus", User.class)
.setParameter("status", "ACTIVE")
.getResultList();
Выбор подхода зависит от сложности запроса, требований к производительности, необходимости динамического построения и предпочтений команды.