Выбрать только некоторые столбцы из таблицы

Есть ли способ выбрать только некоторые столбцы из таблицы с помощью jpa?

Мои таблицы огромны, и мне не разрешено отображать все столбцы в моих объектах. Я попытался создать объект (кстати, в моих таблицах нет PK):

@Entity
@Table(name = "SuperCat")
@Getter
@Setter
public class Cat{

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;

@Column(name = "nameCat")
private String name;
}

а затем в моем репозитории на

public interface CatRepository extends 
CrudRepository<Cat, Long> {

@Query(
  "SELECT name FROM Cat")
Page<Cat> getAlCats(Pageable pageable);

Это всего лишь простой пример, но идея та же. Я много искал и нашел прогнозы, но там вам нужно отобразить всю таблицу, затем я нашел собственные запросы, но все еще не применяется. Я знаю, что могу вернуть объект, а другое решение - использовать запрос с NEW и создать свой собственный объект (без @entity, как pojo). Но есть ли способ сделать это с помощью jpa, чтобы иметь возможность использовать репозиторий и службы, если я создаю свой собственный pojo, я создам класс @transactional, помещаю туда запросы (с NEW), и это все. Мне не нравится этот подход, и я не думаю, что jpa не позволяет вам выбирать только некоторые столбцы, но я не нашел подходящего способа. Может быть, вы спросите, каков будет результат, если я сделаю так: Я получаю эту ошибку: «Невозможно создать TypedQuery для запроса с более чем одним возвратом с использованием запрошенного типа результата [java.lang.Long]» (Для новых запросов я говорю о: http://www.java2s.com/Tutorials/Java/JPA/4800__JPA_Query_new_Object.htm, возможно, я не понял)

Попробуйте добавить атрибут @Transient к тем столбцам, которые вы не хотите сохранять / читать.

OldProgrammer 15.11.2018 18:25

Я хочу прочитать все столбцы (атрибуты), которые находятся в моем классе сущности, есть 8 атрибутов (помеченных столбцом и именем), но в моих таблицах более 100 столбцов, и мне не разрешено добавлять атрибут для этих столбцов в моем код

agata 15.11.2018 18:53

Мой код не будет принят, если они увидят все эти столбцы в моем классе

agata 15.11.2018 18:55

Что вы имеете в виду под Я нашла проекции, но там нужно нанести на карту всю таблицу? См. Мой ответ на этот вопрос. Есть какой-нибудь mapping to a whole table?

pirho 15.11.2018 19:08

Насколько я понимаю, у вас есть объект testClass (который содержит все ваши столбцы) и tupleDto (который содержит именно то, что вам нужно - в моем случае 8 столбцов), и вы создаете запрос с новым (я уже упоминал об этом) . Поправьте меня, может я все неправильно понял. В testClass вам нужно иметь все столбцы или только некоторые из них?

agata 15.11.2018 19:14

Моя проблема в том, что «я не знаю», как создать testClass.

agata 15.11.2018 19:15

Если вы создаете JPQL с предложением select, выбирая только несколько столбцов, тогда у вас есть только эти столбцы, отображаемые в классе результатов. А проблема в том? !! Почему бы на самом деле не попробовать и не рассказать людям, какую «ошибку» вы получаете? У вас могут быть дополнительные столбцы в таблице, которые не сопоставлены с полем ... Поставщик JPA должен просто игнорировать их (если они имеют значение DEFAULT, определенное для этих дополнительных столбцов, когда вы сохраняете новые объекты)

user3973283 15.11.2018 19:34

Если вы прочитали мой пост, я поместил туда ошибку. Я уже пробовал. Я создал класс сущности только с 8 столбцами (из более чем 100), создал репозиторий и в нем запрос. Именно так я добавил сюда код. И он не работает, я понял, в чем проблема, я подумал, что, возможно, из-за того, что мой идентификатор отсутствует в запросе, и я добавил его, но результатом была ошибка, что-то вроде «идентификатор не может быть найден в базе данных, я не Точно не помню). Вот почему я разместил здесь, не то чтобы я ищу легкий путь. В конце сделаю поджо, но подумала, что может есть другой способ

agata 15.11.2018 19:41

Я не хочу упорствовать, я хочу только читать. Итак, если это должно сработать, то что-то не так с идентификатором? (Потому что у меня нет идентификатора в моей таблице).

agata 15.11.2018 19:44

JPA API - это не ваша проблема ... но вы им не пользуетесь. Вы используете Spring Data JPA, другое дело. Предположительно, что "Long" в вашем классе XXXRepository - это то, что Spring интерпретирует как тип, возвращаемый из запроса, поэтому измените его. Базовый запрос JPA позволяет именно то, что вы хотите сделать ... просто выберите несколько столбцов, и запрос JPQL вернет каждую строку как Object[] в соответствии со спецификацией JPA

user3973283 15.11.2018 20:02

Итак, возвращение будет объектом, а затем мне нужно сопоставить объект. Поэтому я не могу вернуть Кота. Хм ... тип возврата, ок. Я это изменю.

agata 15.11.2018 20:11
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
11
672
2

Ответы 2

Вы можете сделать то же самое, используя нижеприведенный подход.

Просто создайте конструктор в классе сущности со всеми необходимыми параметрами, а затем в запросе jpa используйте новый оператор в запросе, как показано ниже.

String query = "SELECT NEW com.dt.es.CustomObject(p.uniquePID)  FROM PatientRegistration AS p";
        TypedQuery<CustomObject> typedQuery = entityManager().createQuery(query , CustomObject.class);
        List<CustomObject> results = typedQuery.getResultList();
        return results;

А класс CustomObject с конструктором должен выглядеть так, как показано ниже.

public class CustomObject {

    private String uniquePID;

    public CustomObject(String uniquePID) {
        super();
        this.uniquePID = uniquePID;
    }

    public String getUniquePID() {
        return uniquePID;
    }

    public void setUniquePID(String uniquePID) {
        this.uniquePID = uniquePID;
    }


}

Да, я подумал об этом подходе (и я начинаю его реализовывать) с использованием простого класса Java и нового в запросе. Но я подумал, что, может быть, Jpa каким-то образом сможет сделать отображение.

agata 15.11.2018 20:07

Я использовал это, и он отлично работает .... AFAIK, это единственный рекомендуемый подход .. :)

Alien 15.11.2018 20:08

Хорошо. А затем у вас есть customObject и класс, помеченные @transactional, где вы реализуете запрос? Я спрашиваю, потому что раньше у меня были репозиторий, служба и сущность.

agata 15.11.2018 20:13

Я вызываю службу из контроллера, а затем обслуживаю репозиторий, и я не аннотировал метод репозитория как @transactional, потому что на самом деле в этом нет необходимости.

Alien 15.11.2018 20:16

Spring-Data-JPA проекция не нужно отображать всю таблицу, просто выберите необходимые поля:

// define the dto interface
public interface CatDto {
  String getName();
  // other necessary fields
  ...
}

@Query(value = "select c.name as name, ... from Cat as c ...)
Page<CatDto> getAllCats(Pageable pageable);

By this way, CatDto is an interface and it only includes some fileds part of the whole table. Its fields name need to match the select field's alias name.

Другие вопросы по теме