Как выбрать несколько полей из Entity в Spring Boot, используя Spring Data? - PullRequest
0 голосов
/ 30 марта 2019

У меня есть случай, когда я хочу отобразить содержимое объекта, но скрыть определенные поля.Моя сущность выглядит следующим образом -

Сущность

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;
    }

И есть класс контроллера, который вызывает класс Service с параметром month для фильтрации набора данных.

То, что я хочу сделать, этоизмените запрос в классе Repository и включите только свойства firstname, middleName и lastName.Класс Repository должен скрывать поле dateOfBirth.Я понимаю, что следующий запрос вернет отфильтрованные элементы -

select d.firstName, d.middleName, d.lastName from StudentDetail d where month(d.dateOfBirth) = ?1 

Однако тип возвращаемого класса Repository имеет тип Entity StudentDetail.Выбор только нескольких полей приведет к ошибке.Итак, я хочу знать, какие изменения я должен внести в классы repo / service и controller (при условии, что изменятся только возвращаемые типы классов)?

1 Ответ

2 голосов
/ 30 марта 2019

Это называется проекция , и Spring предлагает вам два способа сделать это.
Имейте в виду, что это существует в терминах JPA, а не только в Spring.

Принимая Repository в качестве отправной точки

@Repository
public interface StudentDetailsRepository extends JpaRepository<StudentDetail, Integer> {
   ...
}

мы можем использовать

  1. interface проекцию на основе
    просто создать интерфейс, который представляет результат, который вы хотите получить

public interface StudentDetailProjection {
   String getFirstName();
   String getMiddleName();
   String getLastName();
}

и добавьте метод к вашему Repository

@Repository
public interface StudentDetailsRepository extends JpaRepository<StudentDetail, Integer> {
   StudentDetailProjection get...(...);
}

Spring автоматически создаст подкласс для этого интерфейса и попросит JPA выполнить запрос, который будет извлекать толькоуказанные поля.

class проекция на основе
работает почти так же, как проекция на основе интерфейса, но прокси и подклассы не требуются, поскольку вы предлагаете Spring конкретный класс.
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
}

Документация идет глубже.

Также необходимо прочитать это сообщение в блоге Влада Михалча, мастера JPA.


Метод может выглядеть примерно так:

@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), поскольку требуется конструктор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...