Можно ли сделать гибкий заказ в @Query? - PullRequest
1 голос
/ 25 июня 2019

Я делаю проект (основной магазин), и в настоящее время я застрял на заказе (например, по цене, названию и т. Д.).Я хочу знать, есть ли какой-нибудь простой способ сделать 1 гибкий запрос для многих случаев, используя order by для моих товаров.Потому что мой код возвращает неупорядоченный список объектов.

Так что в этом проекте я отправляю запрос на сервер после того, как пользователь выбирает тип сортировки в элементе комбинированного списка.После этого мой контроллер выбирает способ заказа, он вызывает запрос, а затем возвращает наши объекты.

Пожалуйста, помогите, и случайно вы можете сказать мне, какой способ переключения (order_type) лучше, вРеализация контроллера или службы?

PS Я использую причину переключения, если отправляю запрос на сервер как [http://localhost:9999/commodities/category-name/CPU/c.name%20asc], контроллер видит только c без .name asc, поэтому я использовал для этого коммутатор.

Код:

Контроллер:

@RestController
@RequestMapping("commodities")
public class CommodityController {

@GetMapping("category-name/{name}/{order_type}")
    public ResponseEntity<List<CommodityDTO>> getCommodityByCategoryNameWithOrder(@PathVariable("name") String categoryName, @PathVariable("order_type") String order_type){
        List<CommodityDTO> byCategoryWithOrder;

        switch(order_type) {

        case "name_asc":
            byCategoryWithOrder = commodityService.getAllByCategoryNameWithOrder(categoryName, "c.name asc");
            break;

        case "name_desc":
            byCategoryWithOrder = commodityService.getAllByCategoryNameWithOrder(categoryName, "c.name desc");
            break;

        case "price_asc":
            byCategoryWithOrder = commodityService.getAllByCategoryNameWithOrder(categoryName, "c.price asc");
            break;

        case "price_desc":
            byCategoryWithOrder = commodityService.getAllByCategoryNameWithOrder(categoryName, "c.price desc");
            break;

        default:
            return null;
        }
        return new ResponseEntity<List<CommodityDTO>>(byCategoryWithOrder,HttpStatus.OK);
    }

Реализация сервиса:

@Service
@Transactional
public class CommodityServiceImpl implements CommodityService{

    @Autowired
    private CommodityRepository commodityRepository;

    @Autowired
    private ObjectMapperUtils objectMapperUtils;

    @Autowired
    private CloudinaryService cloudinaryService;

    @Override
    public List<CommodityDTO> getAllByCategoryNameWithOrder(String categoryName, String order_type){
            System.out.println("\n\n\n\nOrder type:\n"+order_type+"\n\n\n\n");
            return objectMapperUtils.mapAll(commodityRepository.findAllByCategoryNameWithOrder(categoryName, order_type), CommodityDTO.class);
        }

}

Хранилище:

    public interface CommodityRepository  extends JpaRepository<Commodity, Integer>{
    @Query("Select c FROM Commodity c "
                + "Join Category ct on c.category.id = ct.id "
                + "where ct.name = ?1 "
                + "order by ?2")
        List<Commodity> findAllByCategoryNameWithOrder(String categoryName, String order_type);
    }

Ответы [ 2 ]

2 голосов
/ 25 июня 2019

Вам следует взглянуть на использование расширения QueryDSL для данных Spring. Это, в сочетании с веб-расширением Spring Data, позволит вам фильтровать объекты по любой комбинации свойств и применять сортировку и разбиение на страницы без написания кода.

Добавьте следующее в вашу конфигурацию, и ваш код будет выглядеть следующим образом:

@EnableSpringDataWebSupport

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#core.extensions.querydsl

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#core.web.type-safe

Смотрите здесь о том, как настроить ваш проект для поддержки QueryDsl:

https://www.baeldung.com/querydsl-with-jpa-tutorial

Контроллер

@GetMapping("/searchCommodities")
public ResponseEntity<List<CommodityDTO>> findCommodities(
         @QuerydslPredicate(root = Commodity.class) Predicate predicate,Pageable pageable){

     return new ResponseEntity<List<CommodityDTO>> 
                (commodityService.getCategories(predicate, pageable), HttpStatus.OK);
}

Услуги

public class CommodityServiceImpl implements CommodityService{
    @Override
    public List<CommodityDTO> getCategories(Predicate predicate, Pageable pageable){
        return objectMapperUtils.mapAll(commodityRepository.findAll(
                       predicate, pageable), CommodityDTO.class);
}

Репозиторий

public interface CommodityRepository  extends JpaRepository<Commodity, Integer>, 
                     QueryDslPredicateExecutor<Commodity>{
    //no query methods required
}

Теперь вы можете звонить, например:

/searchCommodities?name=someName&sort=someProperty

/searchCommodities?name=someName&someOtherproperty=xyz&sort=someProperty,desc&sort=someProperty,asc

/searchCommodities?name=x&name=y&name=z //name = x or y or z
0 голосов
/ 25 июня 2019

Есть два варианта:

  1. Используйте вместо этого jOOQ, если вы хотите написать свои собственные запросы.
  2. Использовать методы запроса Spring Data и передавать в качестве дополнительного параметра объект Sort.
...