[英]How to select few fields from a Entity in Spring Boot using Spring Data?
I have a use case where I want to display the contents of an entity but hide certain fields. 我有一个用例,其中我想显示实体的内容,但隐藏某些字段。 My entity is as follows - 我的实体如下-
Entity 实体
public class StudentDetail {
@Id
private Long ID;
private String firstName;
private String middleName;
private String lastName;
@JsonFormat(pattern="dd-MMM-yyyy", timezone="IST")
@Temporal(TemporalType.DATE)
private Date dateOfBirth;
}
It has many other properties as well which I am not showing here. 它还具有许多其他属性,我在这里没有显示。
Repository - 储存库-
@Repository
public interface StudentDetailsRepository extends JpaRepository<StudentDetail, Integer> {
@Query("select d from StudentDetail d where month(d.dateOfBirth) = ?1 ")
List<StudentDetail> getStudentListBasedOnDateOfBirth(int month);
}
Service class - 服务等级-
public List<StudentDetail> getStudentBirthdayDetails(int month) {
List<StudentDetail> StudentDetail = StudentDetailsRepository.getStudentListBasedOnDateOfBirth(month);
return StudentDetail;
}
And there is a controller class which calls the Service class with a month
parameter to filter the data set. 还有一个控制器类,该类通过一个month
参数调用Service类来过滤数据集。
What I want to do is modify the query in Repository class and include only the firstname
, middleName
and lastName
property. 我想做的是修改Repository类中的查询,并仅包含firstname
, middleName
和lastName
属性。 The Repository class should hide the dateOfBirth
field. Repository类应隐藏dateOfBirth
字段。 I realise that the following query will return the filtered items - 我意识到以下查询将返回过滤后的项目-
select d.firstName, d.middleName, d.lastName from StudentDetail d where month(d.dateOfBirth) = ?1
However, the return type of the Repository
class is of Entity Type StudentDetail . 但是, Repository
类的返回类型为Entity Type StudentDetail。 Selecting only few fields from it will result in error. 从中仅选择几个字段将导致错误。 So, I want to know what changes should I make in the repo
/ service
and controller
class (assuming only return types of the classes will change ) ? 因此,我想知道应该对repo
/ service
和controller
类进行哪些更改(假设仅返回类的类型会更改)?
This is called projection , and Spring offers you two ways to accomplish it. 这就是所谓的projection ,Spring为您提供了两种方法来实现它。
Keep in mind this exists in JPA terms, not only in Spring. 请记住,这不仅以Spring的形式存在于JPA术语中。
Taking your Repository
as a starting point 以您的Repository
为起点
@Repository
public interface StudentDetailsRepository extends JpaRepository<StudentDetail, Integer> {
...
}
we can use 我们可以用
interface
-based projection 基于interface
的投影 public interface StudentDetailProjection {
String getFirstName();
String getMiddleName();
String getLastName();
}
and add a method to your Repository
并向您的Repository
添加方法
@Repository
public interface StudentDetailsRepository extends JpaRepository<StudentDetail, Integer> {
StudentDetailProjection get...(...);
}
Spring will subclass that interface automatically and it will ask JPA to execute a query which will extract only the specified fields. Spring将自动对该接口进行子类化,它将要求JPA执行查询,该查询仅提取指定的字段。
class
-based projection 基于class
的投影 public class StudentDetailProjection {
private final String getFirstName;
private final String getMiddleName;
private final String getLastName;
public StudentDetailProjection(
final String getFirstName,
final String getMiddleName,
final String getLastName,
) {...}
// Getters
}
Documentation goes more in depth. 文档更深入。
Also, a must read is this blog post by Vlad Mihalcea, the master of JPA. 另外,必须阅读的是JPA的大师Vlad Mihalcea的这篇博客文章。
The method might look, approximately, like 该方法大概看起来像
@Query("select new your.package.StudentDetailProjection(d.firstName, d.middleName, d.lastName) from StudentDetail d where month(d.dateOfBirth) = ?1")
List<StudentDetailProjection> getStudentListBasedOnDateOfBirth(final int month);
This will go along the concrete class
option (2), because a constructor is required. 这将沿着具体的class
选项(2)进行,因为需要构造函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.