Как отобразить результат из собственного результата запроса, включающего столбцы из нескольких таблиц, в пользовательский класс с использованием репозитория JPA? - PullRequest
1 голос
/ 23 апреля 2020

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

@Repository
public interface CartRepository extends JpaRepository<Cart, Long> {

    @Query(value = "Select i.item_desc, i.item_name ,sum(price) as price, count(*) as quantity from items  i, cart_items ci, cart c where ci.items_item_id=i.item_id and c.id = ci.cart_id and c.user_id = :userId group by ci.items_item_id", nativeQuery = true)
    public List<Object> getCartItemsForCustomer(long userId);

}

Результат запроса будет иметь четыре поля: item_des c, item_name, цена и количество.

Я создал класс DTO для возврата результатов как список объекта DTO.

public class CartItemDto {

   private String itemName;
   private String itemDesc;
   private Long price;
   private Integer quanity;
}

Я не понимаю, как отобразить результат в пользовательский класс dto.

List<Object> objs = cartRepository.getCartItemsForCustomer(userId);

Пожалуйста, предложите способ преобразования списка объектов. Список пользовательских классов.

Ответы [ 2 ]

3 голосов
/ 23 апреля 2020

Вы можете решить эту проблему, используя Проекции на основе интерфейса , например:

@Query(value = "Select i.item_desc as itemDesc, i.item_name as itemName, sum(price) as price, count(*) as quantity from items  i, cart_items ci, cart c where ci.items_item_id=i.item_id and c.id = ci.cart_id and c.user_id = ?1 group by ci.items_item_id", nativeQuery = true)
public List<CartItemInterface> getCartItemsForCustomer(long userId);

CartItemInterface

public interface CartItemInterface {

    String getItemDesc();
    String getItemName();
    Long getPrice();
    Integer getQuantity();
}
0 голосов
/ 23 апреля 2020

Вы можете использовать проекцию DTO и сопоставить столбцы с Java объектом.

  • Вам необходимо создать конструктор, который принимает эти четыре поля и создает объект.
  • change запрос на выборку, чтобы дать полное имя класса и вызвать его конструктор.

Примечание: Если вы используете класс stati c, тогда используйте ссылку вместо $ (.)

public class CartItemDto {
   private String itemName;
   private String itemDesc;
   private Long price;
   private Integer quanity;
   public CartItemDto(String itemName, String itemDesc, Long price, Integer quanity) {
      this.itemName = itemName;
      this.itemDesc = itemDesc;
      this.price = price;
      this.quantity = quantity;
   }   

}

Теперь обновите запрос, чтобы создать экземпляр объекта dto для каждой строки в наборе результатов и вернуть список объектов CartItemDto.

@Query(value = "Select new com.package.CartItemDto(i.item_desc, i.item_name ,sum(price), count(*)) from items  i, cart_items ci, cart c where ci.items_item_id=i.item_id and c.id = ci.cart_id and c.user_id = :userId group by ci.items_item_id")
    public List<CartItemDto> getCartItemsForCustomer(long userId);

Примечание. Это не будет работать с нативными запросами. вам нужно обновить запрос и изменить имена столбцов и таблиц на имена полей и сущностей. Также измените флаг nativeQuery на false (по умолчанию это false, поэтому просто удалите его)

...