SpringDataJPA:使用Pageable,但使用实体的一组特定字段
我正在使用SpringDataJPA:使用Pageable,但使用实体的一组特定字段,jpa,spring-data,spring-data-jpa,Jpa,Spring Data,Spring Data Jpa,我正在使用Spring数据2.0.6.RELEASE 我正在为性能和演示目的进行分页。 关于性能,我想说的是,如果我们有很多记录,最好通过页面显示它们 我有以下几点,工作很好: interface PersonaDataJpaCrudRepository extends PagingAndSortingRepository<Persona, String> { } 通过Thymeleaf我可以应用分页。因此,在此之前,目标已经实现 注意:角色类用JPA注释(@Entity,Id等)
Spring数据
2.0.6.RELEASE
我正在为性能和演示目的进行分页。
关于性能,我想说的是,如果我们有很多记录,最好通过页面显示它们
我有以下几点,工作很好:
interface PersonaDataJpaCrudRepository extends PagingAndSortingRepository<Persona, String> {
}
通过Thymeleaf
我可以应用分页。因此,在此之前,目标已经实现
注意:角色类用JPA
注释(@Entity
,Id
等)
现在我关心的是:即使分页在Spring数据中起作用,关于记录的数量,那么每个记录的内容呢
我的意思是:让我们假设Persona
类包含20个字段(考虑应用程序所需的任何实体),因此对于基于html
的视图,其中报告仅使用4个字段(id、firstname、lastname、date),因此内存中每个实体都有16个不必要的字段
我尝试了以下方法:
interface PersonaDataJpaCrudRepository extends PagingAndSortingRepository<Persona, String> {
@Query("SELECT p.id, id.nombre, id.apellido, id.fecha FROM Persona p")
@Override
Page<Persona> findAll(Pageable pageable);
}
java.lang.ClassCastException:
[Ljava.lang.Object; cannot be cast to com.manuel.jordan.domain.Persona
如果我避免视图失败,请执行以下操作:
Caused by:
org.springframework.expression.spel.SpelEvaluationException:
EL1008E:
Property or field 'id' cannot be found on object of type
'java.lang.Object[]' - maybe not public or not valid?
我读过很多文章,比如:
我理解答案,并且我同意对象[]
返回类型,因为我使用的是特定的字段集
每个实体的完整字段集是否为必填项?在这种情况下,我是否应该接受16个从未使用过的字段的内存成本?检索到的每一条记录都有它吗
是否有一种解决方案可以使用一组特定的字段或Object[]
以及当前的Spring数据的API解决问题
如果只想读取一组特定的列,则不需要获取整个实体。创建包含请求列的类-例如:
public class PersonBasicData {
private String firstName;
private String lastName;
public PersonBasicData(String firstName, String lastName) {
this.firstName = fistName;
this.lastName = lastName;
}
// getters and setters if needed
}
然后,您可以使用构造函数表达式在存储库方法上使用@query
注释指定查询,如下所示:
@Query("SELECT NEW some.package.PersonBasicData(p.firstName, p.lastName) FROM Person AS p")
您还可以使用Criteria API以编程方式完成:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<PersonBasicData> query = cb.createQuery(PersonBasicData.class);
Root<Person> person = query.from(Person.class);
query.multiselect(person.get("firstName"), person.get("lastName"));
List<PersonBasicData> results = entityManager.createQuery(query).getResultList();
CriteriaBuilder cb=entityManager.getCriteriaBuilder();
CriteriaQuery=cb.createQuery(PersonBasicData.class);
Root person=query.from(person.class);
query.multiselect(person.get(“firstName”)、person.get(“lastName”);
List results=entityManager.createQuery(query.getResultList();
请注意,PersonBasicCDATA
的实例仅为读取目的而创建-您将无法对其进行更改并将其保留在数据库中,因为该类未标记为实体,因此您的JPA提供程序将无法使用它。如果您只想读取一组特定的列,则无需获取整个实体。创建包含请求列的类-例如:
public class PersonBasicData {
private String firstName;
private String lastName;
public PersonBasicData(String firstName, String lastName) {
this.firstName = fistName;
this.lastName = lastName;
}
// getters and setters if needed
}
然后,您可以使用构造函数表达式在存储库方法上使用@query
注释指定查询,如下所示:
@Query("SELECT NEW some.package.PersonBasicData(p.firstName, p.lastName) FROM Person AS p")
您还可以使用Criteria API以编程方式完成:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<PersonBasicData> query = cb.createQuery(PersonBasicData.class);
Root<Person> person = query.from(Person.class);
query.multiselect(person.get("firstName"), person.get("lastName"));
List<PersonBasicData> results = entityManager.createQuery(query).getResultList();
CriteriaBuilder cb=entityManager.getCriteriaBuilder();
CriteriaQuery=cb.createQuery(PersonBasicData.class);
Root person=query.from(person.class);
query.multiselect(person.get(“firstName”)、person.get(“lastName”);
List results=entityManager.createQuery(query.getResultList();
请注意,PersonBasicCDATA的实例仅为读取目的而创建-您将无法对其进行更改并将其保留在数据库中,因为该类未标记为实体,因此您的JPA提供程序将无法使用它。查看Spring数据。例如,基于接口的投影可用于通过特定的getter方法公开某些属性
接口:
interface PersonaSubset {
long getId();
String getNombre();
String getApellido();
String getFecha();
}
存储库方法:
Page<PersonaSubset> findAll(Pageable pageable);
Page findAll(可分页);
查看弹簧数据。例如,基于接口的投影可用于通过特定的getter方法公开某些属性
接口:
interface PersonaSubset {
long getId();
String getNombre();
String getApellido();
String getFecha();
}
存储库方法:
Page<PersonaSubset> findAll(Pageable pageable);
Page findAll(可分页);