Во-первых, вы работаете с сущностями, а не с таблицами, поэтому я предполагаю следующее сопоставление для фрукта:
@Entity
public class Fruit {
@Id int id;
String name;
String color;
}
Когда результат состоит из отдельных столбцов, аргумент типа для запроса - Object []. Class (результатом будет список объектов []).Другая возможность - использовать Tuple.Вы можете построить запрос, который вы описали с помощью следующего.Просто для ясности о типе аргумента для примера, промежуточные переменные созданы для Предикатов и ParameterExpressions.Вы также можете включить их в создание запроса.
CriteriaQuery<Object[]> myquery = cb.createQuery(Object[].class);
Root<Fruit> root = myquery.from(Fruit.class);
ParameterExpression<String> nameParamExp = cb.parameter(String.class, "name");
ParameterExpression<String> colorParamExp = cb.parameter(String.class, "color");
Predicate namePredicate = cb.like(root.<String>get("name"), colorParamExp);
Predicate colorPredicate = cb.equal(root.get("color"), nameParamExp);
myquery.multiselect(root.get("id"), root.get("name"), root.get("color"))
.where(cb.and(namePredicate, colorPredicate));
TypedQuery<Object[]> someFruits = em.createQuery(myquery);
someFruits.setParameter("name", "XY%");
someFruits.setParameter("color", "orange");
someFruits.getResultList();
Вы также можете построить тот же запрос, вставив все:
myquery.multiselect(root.get("id"), root.get("name"), root.get("color"))
.where(cb.and(
cb.like(root.<String>get("name"), "XY%"),
cb.equal(root.get("color"), "orange")));
Или использовать Tuple в качестве типа результата:
CriteriaQuery<Tuple> myquery = cb.createQuery(Tuple.class);
Root<Fruit> root = myquery.from(Fruit.class);
myquery.select(cb.tuple(root.get("id").alias("id"),
root.get("name").alias("name"),
root.get("color").alias("color")))
.where(cb.and(
cb.like(root.<String>get("name"), "XY%"),
cb.equal(root.get("color"), "orange")));
TypedQuery<Tuple> someFruits = em.createQuery(myquery);
for (Tuple t: someFruits.getResultList()) {
//access your results by alias set in query instead of using array index
Integer id = t.get("id", Integer.class);
String name = t.get("name", String.class);
String color = t.get("color", String.class);
}
Если вы выберете каноническую метамодель, то вам нужен следующий класс в одной упаковке с вашим фруктом.Вы сами пишете это или генерируете с помощью какого-либо инструмента (например, с помощью org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor).В первый раз имеет смысл написать это самостоятельно:
@StaticMetamodel(Fruit.class)
public abstract class Fruit_ {
public static volatile SingularAttribute<Fruit, Integer> id;
public static volatile SingularAttribute<Fruit, String> color;
public static volatile SingularAttribute<Fruit, String> name;
}
Затем вы можете перейти к строго типизированным аргументам и заменить запрос в предыдущем примере кортежа следующим:
myquery.select(cb.tuple(root.get(Fruit_.id).alias("id"),
root.get(Fruit_.name).alias("name"),
root.get(Fruit_.color).alias("color")))
.where(cb.and(
cb.like(root.get(Fruit_.name), "XY%"),
cb.equal(root.get(Fruit_.color), "orange")));