Есть ли способ выбрать только некоторые столбцы из таблицы с помощью 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, возможно, я не понял)
Я хочу прочитать все столбцы (атрибуты), которые находятся в моем классе сущности, есть 8 атрибутов (помеченных столбцом и именем), но в моих таблицах более 100 столбцов, и мне не разрешено добавлять атрибут для этих столбцов в моем код
Мой код не будет принят, если они увидят все эти столбцы в моем классе
Что вы имеете в виду под Я нашла проекции, но там нужно нанести на карту всю таблицу? См. Мой ответ на этот вопрос. Есть какой-нибудь mapping to a whole table?
Насколько я понимаю, у вас есть объект testClass (который содержит все ваши столбцы) и tupleDto (который содержит именно то, что вам нужно - в моем случае 8 столбцов), и вы создаете запрос с новым (я уже упоминал об этом) . Поправьте меня, может я все неправильно понял. В testClass вам нужно иметь все столбцы или только некоторые из них?
Моя проблема в том, что «я не знаю», как создать testClass.
Если вы создаете JPQL с предложением select, выбирая только несколько столбцов, тогда у вас есть только эти столбцы, отображаемые в классе результатов. А проблема в том? !! Почему бы на самом деле не попробовать и не рассказать людям, какую «ошибку» вы получаете? У вас могут быть дополнительные столбцы в таблице, которые не сопоставлены с полем ... Поставщик JPA должен просто игнорировать их (если они имеют значение DEFAULT, определенное для этих дополнительных столбцов, когда вы сохраняете новые объекты)
Если вы прочитали мой пост, я поместил туда ошибку. Я уже пробовал. Я создал класс сущности только с 8 столбцами (из более чем 100), создал репозиторий и в нем запрос. Именно так я добавил сюда код. И он не работает, я понял, в чем проблема, я подумал, что, возможно, из-за того, что мой идентификатор отсутствует в запросе, и я добавил его, но результатом была ошибка, что-то вроде «идентификатор не может быть найден в базе данных, я не Точно не помню). Вот почему я разместил здесь, не то чтобы я ищу легкий путь. В конце сделаю поджо, но подумала, что может есть другой способ
Я не хочу упорствовать, я хочу только читать. Итак, если это должно сработать, то что-то не так с идентификатором? (Потому что у меня нет идентификатора в моей таблице).
JPA API - это не ваша проблема ... но вы им не пользуетесь. Вы используете Spring Data JPA, другое дело. Предположительно, что "Long" в вашем классе XXXRepository - это то, что Spring интерпретирует как тип, возвращаемый из запроса, поэтому измените его. Базовый запрос JPA позволяет именно то, что вы хотите сделать ... просто выберите несколько столбцов, и запрос JPQL вернет каждую строку как Object[] в соответствии со спецификацией JPA
Итак, возвращение будет объектом, а затем мне нужно сопоставить объект. Поэтому я не могу вернуть Кота. Хм ... тип возврата, ок. Я это изменю.




Вы можете сделать то же самое, используя нижеприведенный подход.
Просто создайте конструктор в классе сущности со всеми необходимыми параметрами, а затем в запросе 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 каким-то образом сможет сделать отображение.
Я использовал это, и он отлично работает .... AFAIK, это единственный рекомендуемый подход .. :)
Хорошо. А затем у вас есть customObject и класс, помеченные @transactional, где вы реализуете запрос? Я спрашиваю, потому что раньше у меня были репозиторий, служба и сущность.
Я вызываю службу из контроллера, а затем обслуживаю репозиторий, и я не аннотировал метод репозитория как @transactional, потому что на самом деле в этом нет необходимости.
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.
Попробуйте добавить атрибут @Transient к тем столбцам, которые вы не хотите сохранять / читать.