我今天发现了JPA 2.0 Criteria API,并想学习它。只是通过一些例子,尝试动手。我的桌上有水果列:
常规的东西:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("fruitManager"); EntityManager em = emf.createEntityManager(); //get the criteria builder CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Fruit> c = cb.createQuery(Fruit.class);
select id, name, color where name like 'XY%' and color='orange'
即如何:
* 仅获取一些列, * 包括通配符搜索, * 在条件的情况下包括AND,OR。
还有什么地方可以通过几种不同类型的SQL查询获得有关“条件”的更多示例?
首先,您要对实体进行操作,而不要对表进行操作,因此我假设对水果进行以下映射:
@Entity public class Fruit { @Id int id; String name; String color; }
当result由不同的列组成时,要查询的类型参数为Object []。class(结果将为Object []的列表)。其他可能性是使用元组。您可以建立以下描述的查询。仅出于示例目的而清楚了参数的类型,为谓词和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")));
或使用元组作为结果类型:
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")));