# 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>執行查詢並取得執行結果。