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