jpa querydsl
在我的上一篇文章中: JPA –基本投影 –我提到了构建JPA投影的两种基本可能性。 这篇文章为您带来了更多示例,这次基于Querydsl框架。 注意,这里我指的是Querydsl版本3.1.1。
重塑构造函数表达式
看下面的代码:
...
import static com.blogspot.vardlokkur.domain.QEmployee.employee;import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;import org.springframework.beans.factory.annotation.Autowired;import com.blogspot.vardlokkur.domain.EmployeeNameProjection;import com.mysema.query.jpa.JPQLTemplates;
import com.mysema.query.jpa.impl.JPAQuery;
import com.mysema.query.types.ConstructorExpression;
...public class ConstructorExpressionExample {...@PersistenceContextprivate EntityManager entityManager;@Autowiredprivate JPQLTemplates jpqlTemplates;public void someMethod() {...final List<EmployeeNameProjection> projections = new JPAQuery(entityManager, jpqlTemplates).from(employee).orderBy(employee.name.asc()).list(ConstructorExpression.create(EmployeeNameProjection.class, employee.employeeId,employee.name));... }...
}
上面的Querydsl构造意味着:创建一个新的JPQL查询[1] [2] ,使用employee作为数据源,使用雇员名[3]排序数据,并返回EmployeeNameProjection的列表,该列表是使用名为的2-arg构造函数构建的员工ID和姓名[4] 。 这与我以前的文章( JPA – Basic Projections )中的构造函数表达式示例非常相似,并导致以下SQL查询:
>select EMPLOYEE_ID, EMPLOYEE_NAME from EMPLOYEE order by EMPLOYEE_NAME asc
如上所示,与JPA构造函数表达式相比,主要优点是使用Java类,而不是在JPQL查询中硬编码的名称。
更重塑的构造函数表达式
Querydsl文档[4]描述了使用构造函数表达式的另一种方式,要求使用@QueryProjection批注和Query Type [1]进行投影,请参见下面的示例。 让我们从修改投影类开始-请注意,我在类构造函数上添加了@QueryProjection批注。
package com.blogspot.vardlokkur.domain;import java.io.Serializable;import javax.annotation.concurrent.Immutable;import com.mysema.query.annotations.QueryProjection;@Immutable
public class EmployeeNameProjection implements Serializable {private final Long employeeId;private final String name;@QueryProjectionpublic EmployeeNameProjection(Long employeeId, String name) {super();this.employeeId = employeeId;this.name = name;}public Long getEmployeeId() {return employeeId;}public String getName() {return name;}}
现在,我们可以通过以下方式使用修改后的投影类(和相应的Query Type [1] ):
...
import static com.blogspot.vardlokkur.domain.QEmployee.employee;import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;import org.springframework.beans.factory.annotation.Autowired;import com.blogspot.vardlokkur.domain.EmployeeNameProjection;
import com.blogspot.vardlokkur.domain.QEmployeeNameProjection;import com.mysema.query.jpa.JPQLTemplates;
import com.mysema.query.jpa.impl.JPAQuery;...public class ConstructorExpressionExample {...@PersistenceContextprivate EntityManager entityManager;@Autowiredprivate JPQLTemplates jpqlTemplates;public void someMethod() {...final List<EmployeeNameProjection> projections = new JPAQuery(entityManager, jpqlTemplates).from(employee).orderBy(employee.name.asc()).list(new QEmployeeNameProjection(employee.employeeId, employee.name));...}...
}
这导致SQL查询:
select EMPLOYEE_ID, EMPLOYEE_NAME from EMPLOYEE order by EMPLOYEE_NAME asc
实际上,当您仔细查看为EmployeeNameProjection ( QEmployeeNameProjection )生成的查询类型[1]时 ,您会发现这是一种用于创建构造函数表达式的“捷径”,如本文第一部分所述。
映射投影
Querydsl使用基于MappingProjection的工厂提供了另一种构建投影的方法。
package com.blogspot.vardlokkur.domain;import static com.blogspot.vardlokkur.domain.QEmployee.employee;import com.mysema.query.Tuple;
import com.mysema.query.types.MappingProjection;public class EmployeeNameProjectionFactory extends MappingProjection<EmployeeNameProjection> {public EmployeeNameProjectionFactory() {super(EmployeeNameProjection.class, employee.employeeId, employee.name);}@Overrideprotected EmployeeNameProjection map(Tuple row) {return new EmployeeNameProjection(row.get(employee.employeeId), row.get(employee.name));}}
上面的类是一个简单的工厂,使用员工ID和名称创建EmployeeNameProjection实例。 请注意,工厂构造函数定义将使用哪些员工属性来构建投影,而map方法定义将如何创建实例。
您可以在下面找到使用工厂的示例:
...
import static com.blogspot.vardlokkur.domain.QEmployee.employee;import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;import org.springframework.beans.factory.annotation.Autowired;import com.blogspot.vardlokkur.domain.EmployeeNameProjection;
import com.blogspot.vardlokkur.domain.EmployeeNameProjectionFactoryimport com.mysema.query.jpa.JPQLTemplates;
import com.mysema.query.jpa.impl.JPAQuery;
...public class MappingProjectionExample {...@PersistenceContextprivate EntityManager entityManager;@Autowiredprivate JPQLTemplates jpqlTemplates;public void someMethod() {...final List<EmployeeNameProjection> projections = new JPAQuery(entityManager, jpqlTemplates).from(employee).orderBy(employee.name.asc()).list(new EmployeeNameProjectionFactory());....}...
}
如您所见,与构造函数表达式示例相比,这里唯一的区别是列表方法调用。
上面的示例再次导致非常简单SQL查询:
select EMPLOYEE_ID, EMPLOYEE_NAME from EMPLOYEE order by EMPLOYEE_NAME asc
这种方式构建投影功能更加强大,并且不需要存在n-arg投影构造函数。
基于QBean的投影(JavaBeans再次出现)
使用基于QBean的 Querydsl创建投影至少还有另一种可能性,在这种情况下,我们使用以下方法构建结果列表:
... .list(Projections.bean(EmployeeNameProjection.class, employee.employeeId, employee.name))
这种方式要求EmployeeNameProjection类遵循JavaBean约定,这在应用程序中并不总是需要的。 如果需要,请使用它,但已被警告
很少有甜点链接
- 使用查询类型
- 查询方式
- 定购
- 构造函数投影
翻译自: https://www.javacodegeeks.com/2013/05/jpa-querydsl-projections.html
jpa querydsl