深入解析JPA查询:从实体到字段的多维选择
在Java Persistence API(JPA)的世界中,数据查询是核心功能之一。JPA提供了多种查询方式,其中Criteria API以其强大的灵活性和表达能力而备受青睐。本文将通过一个详细的教程,展示如何使用Criteria API进行字段选择查询,包括单字段和多字段的查询实例。
实体选择
在之前的示例中,我们学习了如何通过使用CriteriaQuery#select()
来选择实体。例如:
CriteriaQuery<Employee> query = criteriaBuilder.createQuery(Employee.class);
Root<Employee> employee = query.from(Employee.class);
query.select(employee);
List<Employee> employees = entityManager.createQuery(query).getResultList();
单字段选择
CriteriaQuery
类的select()
方法签名如下:
CriteriaQuery<T> select(Selection<? extends T> selection);
参数Selection
定义了查询结果中要返回的项。在上述实体选择示例中,我们选择了Root<Employee>
(query.select(employee)
)。Root
类实现了Selection
接口。要选择非实体的单个字段,我们可以使用Root.get()
方法,它返回一个Path
实例(也是Selection
的子接口)。
例如:
CriteriaQuery<String> query = criteriaBuilder.createQuery(String.class);
Root<Employee> employee = query.from(Employee.class);
query.select(employee.get("name"));
List<String> list = entityManager.createQuery(query).getResultList();
或者使用元模型对象:
query.select(employee.get(Employee_.name));
多字段选择
选择多个字段时,我们需要将CompoundSelection
(Selection
的子接口)传递给CriteriaQuery#select()
方法。创建CompoundSelection
的一种方式是使用CriteriaBuilder
的array()
方法:
CompoundSelection<Object[]> array(Selection<?>... selections);
例如:
CriteriaQuery<Object[]> query = criteriaBuilder.createQuery(Object[].class);
Root<Employee> employee = query.from(Employee.class);
query.select(criteriaBuilder.array(employee.get(Employee_.id), employee.get(Employee_.name)));
List<Object[]> list = entityManager.createQuery(query).getResultList();
或者,我们可以使用CriteriaQuery#multiselect()
代替CriteriaQuery#select()
:
CriteriaQuery<Object[]> query = criteriaBuilder.createQuery(Object[].class);
Root<Employee> employee = query.from(Employee.class);
query.multiselect(employee.get(Employee_.name), employee.get(Employee_.salary));
List<Object[]> list = entityManager.createQuery(query).getResultList();
根据CriteriaQuery#multiselect()
文档,如果查询的类型是CriteriaQuery<Object>
或者在创建查询时没有指定类型,并且multiselect
方法只传递了一个参数,则每行返回一个Object
类型的实例。
如果查询的类型是CriteriaQuery<Object>
或者在创建查询时没有指定类型,并且multiselect
方法传递了多个参数,则会为每行实例化并返回一个Object[]
类型的实例。数组的元素将对应于multiselect
方法的参数,按照指定的顺序。
示例
以下是Employee
实体和ExampleMain
主类的定义,以及如何使用上述查询方法的示例。
@Entity
public class Employee {
@Id
private long id;
private String name;
private double salary;
private String dept;
// ...
}
public class ExampleMain {
// ...
public static void main(String[] args) {
// ...
persistEmployees();
findAllEmployeeEntities();
findEmployeeNames();
findEmployeeNamesAndIds();
findEmployeeNamesAndSalaries();
}
// ...
}
在main
方法中,我们首先持久化员工数据,然后通过不同的查询方法来检索数据,包括实体选择、单字段选择和多字段选择。
示例项目
本示例项目使用了以下依赖和技术:
- h2 1.4.197: H2数据库引擎。
- hibernate-core 5.3.2.Final: Hibernate的核心ORM功能。
- hibernate-jpamodelgen 5.3.2.Final: 注解处理器,用于生成JPA 2静态元模型类。
- JDK 1.8
- Maven 3.5.4
通过本教程,你将能够深入理解JPA的Criteria API,并掌握如何进行灵活的字段选择查询。 ```