---
# System prepended metadata

title: Criteria API
tags: [specification, typesafe, persistence, query, jpa]

---

# Criteria API
###### tags: `jpa` `persistence` `query` `specification` `typesafe`
以物件導向的概念建立 [typesafe](https://en.wikipedia.org/wiki/Type_safety) 的查詢，以滿足多變的、無法預期的篩選條件；立馬看個範例，以下這段 JPQL：

```sql
SELECT p FROM Pet p
```

若用 Criteria API 則變成：

```java
@PersistenceContext
EntityManager entityManager;

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Pet> criteriaQuery = criteriaBuilder.createQuery(Pet.class);
Root<Pet> root = criteriaQuery.from(Pet.class);
criteriaQuery.select(root);
TypedQuery<Pet> typedQuery = entityManager.createQuery(criteriaQuery);
List<Pet> results = typedQuery.getResultList();
```

~~靠，本來那麼單純的一個查詢要搞得那麼複雜是尛！~~
1. 首先取得```EntityManager```<sup>[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](https://javaee.github.io/javaee-spec/javadocs/javax/persistence/EntityManager.html)</sup>。
2. 呼叫```entityManager.getCriteriaBuilder()```<sup>[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](https://javaee.github.io/javaee-spec/javadocs/javax/persistence/EntityManager.html#getCriteriaBuilder--)</sup>取得```CriteriaBuilder```<sup>[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](https://javaee.github.io/javaee-spec/javadocs/javax/persistence/criteria/CriteriaBuilder.html)</sup>。
3. 呼叫```criteriaBuilder.createQuery(Class<T> resultClass)```<sup>[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](https://javaee.github.io/javaee-spec/javadocs/javax/persistence/criteria/CriteriaBuilder.html#createQuery-java.lang.Class-)</sup>建立```CriteriaQuery```<sup>[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](https://javaee.github.io/javaee-spec/javadocs/javax/persistence/criteria/CriteriaQuery.html)</sup>，也就是所謂的**動態查詢物件**<sub>(可透過物件導向的方式搞出最後欲產生出來的**查詢**)</sub>。
4. 呼叫```criteriaQuery.from(Class<X> entityClass)```<sup>[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](https://javaee.github.io/javaee-spec/javadocs/javax/persistence/criteria/AbstractQuery.html#from-java.lang.Class-)</sup>指定主要的 entity<sub>(也就是資料表啦)</sub>。
5. 呼叫```criteriaQuery.select(Selection<? extends T> selection)```<sup>[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](https://javaee.github.io/javaee-spec/javadocs/javax/persistence/criteria/CriteriaQuery.html#select-javax.persistence.criteria.Selection-)</sup>指定查詢結果的資料型態。
6. 呼叫```entityManager.createQuery(CriteriaQuery<T> criteriaQuery)```<sup>[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](https://javaee.github.io/javaee-spec/javadocs/javax/persistence/EntityManager.html#createQuery-javax.persistence.criteria.CriteriaQuery-)</sup>建立指定了查詢結果的資料型態的```TypedQuery<T>```<sup>[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](https://javaee.github.io/javaee-spec/javadocs/javax/persistence/TypedQuery.html)</sup>以備執行。
7. 呼叫```typedQuery.getResultList()```<sup>[![JavaDoc](https://i.imgur.com/7EkdyXl.png)](https://javaee.github.io/javaee-spec/javadocs/javax/persistence/TypedQuery.html#getResultList--)</sup>執行查詢並取得執行結果。