我有一个用例,我想显示实体的内容,但隐藏某些字段。我的实体如下-
实体
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;
}
它还有许多其他属性,我在这里没有显示。
存储库-
@Repository
public interface StudentDetailsRepository extends JpaRepository<StudentDetail, Integer> {
@Query("select d from StudentDetail d where month(d.dateOfBirth) = ?1 ")
List<StudentDetail> getStudentListBasedOnDateOfBirth(int month);
}
服务类-
public List<StudentDetail> getStudentBirthdayDetails(int month) {
List<StudentDetail> StudentDetail = StudentDetailsRepository.getStudentListBasedOnDateOfBirth(month);
return StudentDetail;
}
有一个控制器类,它使用month
参数调用Service类来过滤数据集。
我想做的是修改Repository类中的查询,并仅包括firstname
,middleName
和lastName
属性。 Repository类应隐藏dateOfBirth
字段。我意识到以下查询将返回已过滤的项目-
select d.firstName, d.middleName, d.lastName from StudentDetail d where month(d.dateOfBirth) = ?1
但是,Repository
类的返回类型为Entity Type StudentDetail。从中仅选择几个字段将导致错误。因此,我想知道应该在repo
/ service
和controller
类中进行哪些更改(假设仅返回类的类型会更改)?
答案 0 :(得分:2)
这称为 projection ,Spring提供了两种方法来实现它。
请记住,这不仅以Spring的形式存在于JPA术语中。
以您的Repository
为起点
@Repository
public interface StudentDetailsRepository extends JpaRepository<StudentDetail, Integer> {
...
}
我们可以使用
interface
的投影public interface StudentDetailProjection {
String getFirstName();
String getMiddleName();
String getLastName();
}
并将方法添加到您的Repository
@Repository
public interface StudentDetailsRepository extends JpaRepository<StudentDetail, Integer> {
StudentDetailProjection get...(...);
}
Spring将自动对该接口进行子类化,它将要求JPA执行查询,该查询仅提取指定的字段。
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更深入。
此外,必须阅读的是this博客,作者是JPA的主人Vlad Mihalcea。
该方法看起来大概像
@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);
这将沿具体的class
选项(2)进行,因为需要构造函数。