假设我有密码,就像:
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()方法,它们之间有什么区别?
发布于 2020-09-04 17:28:21
CriteriaBuilder#createQuery(Class resultClass)创建CriteriaQuery
和
EntityManager#createQuery(CriteriaQuery criteriaQuery)创建TypedQuery。
TL;DR:
这两种类型不是彼此的选择,而是为了不同的目的:
CriteriaQuery<T>用于以编程方式定义查询,而不是手动编写查询,TypedQuery<T>用于避免在使用Query时必须进行的转换。你甚至可以将两者结合使用,我将向你展示-如何使用。
现在,让我们看一下更多的细节。
TypedQuery<T>
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.在这里,重要的点是,在所有这些情况下,您必须手动编写或JPQL查询,以构造相应的Query实例,然后将调用相应的方法。
CriteriaQuery<T>
JPA标准API用于通过构造基于对象的查询定义对象来定义查询,而不是使用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>);https://stackoverflow.com/questions/63743774
复制相似问题