criteriabuilder.createquery和entitymanager.createquery之间有什么区别?

camsedfj  于 2021-07-05  发布在  Java
关注(0)|答案(1)|浏览(412)

关闭。这个问题需要细节或清晰。它目前不接受答案。
**想改进这个问题吗?**通过编辑这个帖子来添加细节并澄清问题。

4个月前关门了。
改进这个问题
假设我有密码,比如:

EntityManager em = ...;
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Root<Pet> pet = cq.from(Pet.class);
cq.select(pet);
TypedQuery<Pet> q = em.createQuery(cq);
List<Pet> allPets = q.getResultList();

有人能解释一下为什么我们要用两个吗 createQuery() 方法和它们之间的区别是什么?

bpzcxfmw

bpzcxfmw1#

CriteriaBuilder#createQuery(Class<T> resultClass) 创建 CriteriaQuery<T>EntityManager#createQuery(CriteriaQuery<T> criteriaQuery) 创建 TypedQuery<T> .

热释光;博士:

这两种类型不是彼此的替代品,而是服务于不同的目的: CriteriaQuery<T> 用于以编程方式定义查询,而不是手动编写,并且 TypedQuery<T> 用于避免在使用 Query . 你甚至可以将两者结合使用,我将向你展示如何使用。
现在,让我们更详细地了解一下。

类型查询

jpa用 Query , TypedQuery<T> 或者 StoredProcedureQuery 示例(全部来自 javax.persistence 包,后两个扩展 Query ).
使用的简单示例 Query 看起来像这样:

Query query = em.createQuery("your select query.."); //you write query
SomeType result = (SomeType) query.getSingleResult(); //cast needed
List<SomeType> resultList = (List<SomeType>) query.getResultList(); //cast needed

请注意 Query api方法返回 Object 或原始类型(无专用类型) List 示例,必须将其强制转换为预期类型。 TypedQuery<T> 另一方面,与 Query 在某种程度上,您可以在创建查询时提供预期返回值的类,并跳过转换部分,如下所示:

TypedQuery<SomeType> typedQuery = em.createQuery("your select query..");
SomeType result = typedQuery.getSingleResult(); //<-- no cast needed.
List<SomeType> result = typedQuery.getResultList(); //<-- no cast needed.

这里重要的一点是,在所有这些情况下,您必须手动编写hql或jpql查询,以便构造相应的 Query 示例,之后您将在其上调用相应的方法。

标准查询

jpa规范2.2:
jpa criteriaapi通过构建基于对象的查询定义对象来定义查询,而不是使用java持久性查询语言的基于字符串的方法。 CriteriaQuery 在概念上和 Query (构建用于从数据库获取数据的查询),这是定义jpql/hql查询的另一种方法。
主要目的 CriteriaQuery<T> 是提供一种编程和类型安全的方式来定义独立于平台的查询。因此,不是手动编写hql/jpql查询,而是通过编程方式构造查询,如下所示:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<SomeType> cq = cb.createQuery(SomeType.class);
Root<SomeType> root = cq.from(SomeType.class);

//programmatically adding criterias and/or some filter clauses to your query
cq.select(root);
cq.orderBy(cb.desc(root.get("id")));

//passing cq to entityManager or session object
TypedQuery<SomeType> typedQuery = entityManager.createQuery(cq);
List<SomeType> list =  typedQuery.getResultList();

回答您的最后一个问题-哪些方法可以访问数据库?:
在上述所有情况下,当您调用 Query (或其子对象)。在我们的例子中,这些是:

query.getSingleResult();
query.getResultList();
typedQuery.getSingleResult();
typedQuery.getResultList();

记住两个步骤:
您可以定义/构造查询对象(使用 HQL , JPQL 或者 CriteriaQuery<T> );
调用该对象上的api方法,这些方法实际上查询数据库。

相关问题