Vic*_*cky 4 hibernate jpa criteria-api jpa-2.0
我今天发现了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);
Run Code Online (Sandbox Code Playgroud)
如何使用条件构建以下查询:
select id, name, color where name like 'XY%' and color='orange'
Run Code Online (Sandbox Code Playgroud)
即如何:
还有什么地方可以通过几种不同类型的SQL查询获得更多关于'Criteria'的例子吗?
Mik*_*unu 13
首先,你操作实体,而不是表,所以我将假设以下映射为水果:
@Entity
public class Fruit {
@Id int id;
String name;
String color;
}
Run Code Online (Sandbox Code Playgroud)
当结果由单独的列组成时,查询的类型参数是Object [] .class(结果将是List of Object []).其他可能性是使用元组.您可以使用以下内容构建您描述的查询.为了清楚地说明参数的类型,为Predicates和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();
Run Code Online (Sandbox Code Playgroud)
您还可以通过内联所有内容来构建相同的查询:
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")));
Run Code Online (Sandbox Code Playgroud)
或者使用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);
}
Run Code Online (Sandbox Code Playgroud)
如果你选择规范的元模型,那么你需要在同一个包中跟随你的水果.您可以自己编写它,也可以使用某些工具生成(例如使用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;
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用强类型参数并在以前的元组示例中替换查询:
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")));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8443 次 |
| 最近记录: |