java - @Query 中是否可以进行灵活的排序?

标签 java spring jpa spring-data-jpa spring-data

我正在制作一个项目(基本商店),目前我坚持订购(例如按价格、名称等)。我想知道是否有任何简单的方法可以对许多情况进行 1 次灵活查询,对我的商品使用 order by 。因为我的代码返回无序列表的对象。

因此,在这个项目中,我在用户在组合框元素中选择排序类型后向服务器发送请求。之后我的 Controller 选择排序方式,它调用查询,然后返回我们的对象。

请帮忙,顺便告诉我在 Controller 或服务实现中哪种 switch(order_type) 方式更好?

附注我使用 switch 因为如果我将请求发送到服务器 [http://localhost:9999/commodities/category-name/CPU/c.name%20asc ] Controller 只能看到 c 而没有 .name asc,这就是我使用 switch 的原因。

代码:

Controller :

@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);
    }

最佳答案

您应该考虑使用 Spring 数据的 QueryDSL 扩展。与 Spring Data Web 扩展相结合,您可以通过任意属性组合来过滤实体,并应用排序和分页而无需编写任何代码。

将以下内容添加到您的配置中,您的代码将如下所示:

@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

Controller

@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

关于java - @Query 中是否可以进行灵活的排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56751237/

相关文章:

java - 如何创建可在整个应用程序中访问但同时请求特定的变量?

java 从字符串中获取键码

java - Tomcat Java Servlet - 在应用程序启动时初始化类

java - 使用 SAML 1.1 的 Spring Security

java - Hibernate/JPA 如何修复子类错误生成数据库表

jpa - 如何在 JPQL where 子句中使用 JPA 枚举?

hibernate - Spring Data JPA - 扩展类字段问题

java - 如何从 TimePicker 创建两个时间值(currentHour 和 currentMinute),然后将它们连接在一起

spring - 如何防止 MappingJackson2XmlHttpMessageConverter 接管序列化?

spring - Grails属性初始化