Spring Data JPA: работа с Pageable, но с определенным набором полей объекта - PullRequest
0 голосов
/ 04 мая 2018

Я работаю с Spring Data 2.0.6.RELEASE.

Я работаю над нумерацией страниц для целей представления и представления. Здесь о производительности я говорю о том, что если у нас много записей, лучше показывать их через страницы

У меня есть следующее и отлично работает:

interface PersonaDataJpaCrudRepository extends PagingAndSortingRepository<Persona, String> {
}

@Controller отлично работает с:

@GetMapping(produces=MediaType.TEXT_HTML_VALUE)
public String findAll(Pageable pageable, Model model){

Через Thymeleaf Я могу применить нумерацию страниц. Поэтому до тех пор, пока здесь цель не будет достигнута.

Примечание: Класс Persona помечен JPA (@Entity, Id и т. Д.)

Теперь меня беспокоит следующее: даже если нумерация записей в Spring Data работает с количеством записей, как насчет содержимого каждой записи?

Я имею в виду: давайте предположим, что класс Persona содержит 20 полей (рассмотрим любую сущность, которую вы хотите для своего приложения), таким образом, для представления, основанного на html, где отчет использует только 4 поля ( id, имя, фамилия, дата), таким образом, у нас есть 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);

}

Если я выполняю простую печать в @Controller, произойдет сбой примерно следующего:

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?

Я прочитал много сообщений в SO, таких как:

Я понимаю ответ и согласен с типом возврата Object[], потому что я работаю с определенным набором полей.

  1. Обязательна ли работа с полным набором полей для каждой сущности? Должен ли я просто принять стоимость памяти о 16 полях в этом случае, которые никогда не используются? Это для каждой найденной записи?
  2. Есть ли решение для обхода с определенным набором полей или Object[] с текущим API Spring Data?

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

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

Интерфейс:

interface PersonaSubset {
    long getId();
    String getNombre();
    String getApellido();
    String getFecha();
}

Метод репозитория:

Page<PersonaSubset> findAll(Pageable pageable);
0 голосов
/ 04 мая 2018

Если вы хотите прочитать только определенный набор столбцов, вам не нужно извлекать всю сущность. Создайте класс, содержащий запрошенные столбцы - например:

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();

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

...