Criteria API 簡介
在 Hibernate 中有兩種寫數據庫查詢的方法:
- 休眠查詢語言
- 標準API
您很久以前就已經遇到過第一個,是時候熟悉 Criteria API 了。這是一個非常強大的工具,在某些時候它甚至比 HQL 更受歡迎。現在它不再那麼流行了,但對於某些任務來說,它肯定是比 HQL 更好的解決方案。
無論如何,不熟悉 Criteria API 就無法學習 Hibernate。我們先寫一個小例子,然後我們來分析。例如,我們會從數據庫中請求所有員工(Employee)。這是我們將得到的:
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Employee> critQuery = builder.createQuery(Employee.class);
Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);
Query<Employee> query = session.createQuery(critQuery);
List<Employee> results = query.getResultList();
看起來很複雜。讓我們編寫相同的 HQL 查詢進行比較:
String hqlQuery = "from Employee";
Query<Employee> query = session.createQuery(hqlQuery);
List<Employee> results = query.getResultList();
請注意,兩個示例的最後兩行幾乎相同:我們創建了一個 Query 對象並使用它來獲取一個 List。這暗示其餘的行正在做相同的事情。
查看第一個示例的第 3 行和第 4 行:
Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);
讓我們把它們寫成一行:
critQuery.select(critQuery.from(Employee.class));
是不是讓你想起了什麼?如果你給它塗上一點不同的顏色:
critQuery.select(critQuery.from(Employee.class));
是的,這是一個非常棘手的 SELECT FROM 查詢結構。
使用 Criteria API 的示例
為了更好地理解,我將僅舉幾個例子。
請求 1。獲取所有工資在1萬以上的員工:
critQuery.select(critQuery.from(Employee.class)).where(builder.gt(root.get("salary"), 10000));
請求 2。獲取所有工資低於5萬的員工:
critQuery.select(critQuery.from(Employee.class)).where(builder.lt(root.get("salary"), 50000));
請求 3。獲取職位名稱中包含單詞“test”的所有員工:
critQuery.select(critQuery.from(Employee.class)).where(builder.like(root.get("occupation"), "%test%"));
請求 4。獲取工資在10到5萬之間的所有員工:
critQuery.select(critQuery.from(Employee.class)).where(builder.between(root.get("salary"), 10000, 50000));
請求 5。獲取名稱為空的所有員工:
critQuery.select(critQuery.from(Employee.class)).where(builder.isNull(root.get("name")));
請求 6。獲取名稱不為空的所有員工:
critQuery.select(critQuery.from(Employee.class)).where(builder.isNotNull(root.get("name")));
這是構建查詢的一種非常棘手的方法:
- 首先你得到對象標準生成器.
- 然後用它來創建一個對象條件查詢.
- 然後你開始向它添加零件條件查詢和標準生成器.
您可以通過以下方式設置參數:
- 選擇
- 從
- 在哪裡
同時使用標準生成器您可以為 WHERE 構造不同的條件。
使用 Criteria API 的高級工作
使用 Criteria API,您可以構建任何復雜性的查詢。這是個好消息。例如,您需要一個複雜的 WHERE 子句。方法如下:
Predicate greaterThan = builder.gt(root.get("salary"), 1000);
Predicate testers = builder.like(root.get("occupation"), "test%");
critQuery.select(critQuery.from(Employee.class)).where(builder.or(greaterThan, testers));
如果你想寫AND而不是OR,那麼你只需要改變最後一行:
critQuery.select(critQuery.from(Employee.class)).where(builder.and(greaterThan, testers));
一切其實都很簡單。讓我給你一個表格和一些比較:
數據庫 | 方法 | 全記錄 |
---|---|---|
一個<乙 | lt(a, b) | builder.lt(a, b) |
一個 > 乙 | GT(a, b) | builder.gt(a,b) |
或 | 或(一,二) | 建造者或(a,b) |
一個和b | 和(一,二) | 建造者和(a,b) |
喜歡b | 喜歡(a,b) | builder.like(a,b) |
(c, d) 之間 | 在(a,c,d)之間 | builder.between(a, c, d) |
一個是空的 | isNull(a) | builder.isNull(a) |
不為空 | isNotNull(a) | builder.isNotNull(a) |
一切都很簡單,不是嗎?
我們如何向查詢添加排序?很簡單的:
critQuery.select( critQuery.from(Employee.class) );
critQuery.where( builder.and(greaterThan, testers) );
critQuery.orderBy( builder.asc(root.get("salary"), builder.desc(root.get("joinDate") )
您只需調用該對象條件查詢orderBy()方法並將所需的參數傳遞給它。
下面是相同查詢在 HQL 中的樣子。比較:
select * from Employee
where (…) and (…)
order by 'salary' asc, 'joinDate' desc
你只需要記住三件事:
- 在對像上調用 SELECT、FROM、WHERE 等關鍵運算符條件查詢.
- 在對像上調用 AND、OR、DESC 等輔助運算符標準生成器.
- 字段名稱通過get()從對像中獲取根.
GO TO FULL VERSION