JPA, где пункт
В JPA запрос выглядит так:
Query q = entityManager.createQuery("select o from Product o WHERE o.category = :value");
q.setParameter("category", category);
Как я могу установить категорию для любой категории в JPA? Поэтому, если пропущена нулевая категория, я просто игнорирую параметр категории, выбираю все товары.
Ответы
Ответ 1
Как установить категорию в любую категорию в JPA? Поэтому, если нулевая категория прошла, я просто игнорирую параметр категории, выбираю все продукты.
Вам нужно будет динамически строить запрос. С помощью HQL (это упрощенный пример):
Map<String, Object> params = new HashMap<String, Object>();
StringBuffer hql = new StringBuffer("from Product p");
boolean first = true;
if (category != null) {
hql.append(first ? " where " : " and ");
hql.append("p.category = :category");
params.put("category", category);
}
// And so on...
Query query = session.createQuery(hql.toString());
Iterator<String> iter = params.keySet().iterator();
while (iter.hasNext()) {
String name = iter.next();
Object value = params.get(name);
query.setParameter(name, value);
}
List results = query.list()
Но, на самом деле, моя рекомендация заключалась бы в использовании API критериев здесь:
Criteria criteria = session.createCriteria(Product.class);
if (category != null) {
criteria.add(Expression.eq("category", category);
}
// And so on...
List results = criteria.list();
Гораздо проще для сложных динамических запросов.
Ответ 2
Чтобы параметры архивирования стали необязательными, вы можете написать запрос без использования API критериев:
select o from Product o WHERE :value is null or :value='' or o.category = :value
Ответ 3
Вы правы почти с небольшими изменениями.
Query query = entityManager.createQuery("select o from Product o WHERE o.category = :value");
query.setParameter("value", category);
в параметре setParamater " (точный текст) должно соответствовать ": значение в запросе.
Ответ 4
Как установить категорию в любую категорию в JPA? Поэтому, если нулевая категория прошло, я просто игнорирую параметр категории, выбираю все продукты.
Вы можете установить категорию в "%".
if (category == null) query.setParameter( "category", "%" );
else query.setParameter( "категория", категория);
Ответ 5
SELECT * FROM PRODUCT WHERE CATEGORY = *
Я думаю, что вы тоже новичок в SQL.
WHERE CATEGORY = *
не означает "любая категория" (это даже не правильный SQL).
Как в SQL, так и в JPA, у вас просто не будет предложения WHERE
вообще, если вы хотите, чтобы какая-либо категория (или в SQL у вас могла быть WHERE CATEGORY IS NOT NULL
).
Ответ 6
Паскаль Тивент дал довольно хороший ответ, порекомендовав использовать Criteria
. Однако Criteria
в его ответе - это чистые критерии Hibernate
. Используя пример JPA Criteria
:
private List<Result> getProduct(String category) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Product> criteria = builder.createQuery(Product.class);
Root<Product> productRoot = criteria.from(Product.class);
if (category != null)
criteria.where(builder.equal(productRoot.get("category"), category))
}
entityManager.createQuery(criteria).getResultList();
}
Ответ 7
То, что вы пытаетесь достичь, является интуитивно понятным с точки зрения шаблона проектирования. Давайте подумаем о проблемах в терминах SQL, игнорируя все JPA и прочее.
Соответствующий SQL-запрос вашего JPQL выглядит ниже
SELECT o.* FROM product o WHERE o.category = 'SOME_CAT';
Теперь, если вы передадите null вместо категории SOME_CAT
SQL будет выглядеть так:
SELECT o.* FROM product o WHERE o.category IS NULL;
Не существует стандарта SQL для инвертирования значения параметра, изменяющего результирующий набор, если ваш SQL не выглядит следующим образом
SELECT o.* FROM product o WHERE o.category IS NOT NULL;
Подобный JPQL будет выглядеть
SELECT o FROM Product o WHERE o.category <> :param
Вы можете видеть, что нам нужно инвертировать логическую операцию вместо манипулирования параметром. Не существует стандартного способа добиться такого поведения, если вы не строите JPQL динамически с условием if else.
Я бы предпочел отдельный обработчик методов для фильтрации по категориям, а другой для перечисления всех независимо от категории.