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()從對像中獲取.