【问题标题】:Mapping controller endpoints to Spring JPA layer将控制器端点映射到 Spring JPA 层
【发布时间】:2020-07-17 09:35:01
【问题描述】:

我已经编写了这个请求映射来通过它的 id 使用可选的请求参数 ticketType 和 ticketStatus 来访问票证:

@GetMapping(path = "/tickets/{ticketId}")
   @ResponseStatus(value = HttpStatus.OK)
    public ResponseEntity<List<TicketResponse>> getTicketsById(@PathVariable("ticketId") final Long ticketId, @RequestParam("ticketType") final String ticketType, @RequestParam("ticketStatus") final String ticketStatus)

当前存储库包含基于ticketId或ticketState返回的方法:

    @Repository
    public interface TicketRepository extends JpaRepository<TicketEntity, Long> {

Stream<TicketEntity> findByTicketIdAndTicketState(@Param("ticketId") Long ticketId);

Stream<TicketEntity> findByTicketIdAndTicketState(@Param("ticketId") Long ticketId, @Param("ticketState") String ticketState);

    }

这些端点应该如何暴露在控制器层?

当前端点是:

@GetMapping(path = "/{ticketId}")
    @ResponseStatus(value = HttpStatus.OK)
    public ResponseEntity<List<TicketResponse>> getTicketsByTicketId(
            @PathVariable("productId") final Long ticketId, @RequestParam(name = "ticketState", required=false) final String ticketState) {

        final List<TicketResponse> ticketsByTicketId = ticketService.getTicketsByTicketId(ticketId);

        if(ticketsByTicketId.size() == 0){
            return ResponseEntity.ok("No tickets found");
        }
        else {
            return ResponseEntity.ok(ticketsByTicketId);
        }

    }

我应该添加一个新端点吗? :

或者更新控制器以根据查询选择要实现的JPA存储库方法?:

@GetMapping(path = "/{ticketId}")
    @ResponseStatus(value = HttpStatus.OK)
    public ResponseEntity<List<TicketResponse>> getTicketsByTicketId(
            @PathVariable("productId") final Long ticketId, @RequestParam(name = "ticketState", required=false) final String ticketState) {

List<TicketResponse> tickets = null;

if(ticketState == null) {
        tickets = ticketService.getTicketsByTicketId(ticketId);
}
else{
tickets = ticketService.getTicketsByTicketIdAndTicketState(ticketId, ticketState);
}

        if(ticketsByTicketId.size() == 0){
            return ResponseEntity.ok("No tickets found");
        }
        else {
            return ResponseEntity.ok(ticketsByTicketId);
        }

    }

JPA 存储库将进一步扩展,以基于更多参数(例如 ticketType、ticketDescription )进行过滤。我只是提到这一点,因为如果需要检查哪个参数为空并选择相关的 JPA 查询,我的控制器逻辑将变得非常复杂。

【问题讨论】:

  • 查找 queryDSL。就我个人而言,我有一个映射并传递一个包含所有可能参数的过滤器对象。然后,您可以使用 queryDSL 根据设置的字段为您的数据库构建查询。
  • 回购中也不需要@Param
  • 另外你为什么要从 JParepo 返回 Streams?
  • @123 我返回一个流以便使用 map 函数 - 返回的实体被映射到另一个数据类型。
  • 哦,我记得在没有@Transactional 的情况下使用它们时会出现问题,连接挂起或其他问题。现在可能已经修好了,但除非必要,否则我可能不会退回它们

标签: java spring spring-boot rest jpa


【解决方案1】:

使用 Spring Data JPA 规范可以解决这个地图过滤问题。 可以使用 Criteria API 构建复杂查询,具体取决于过滤参数。

A good article about JPA Specification

【讨论】:

    猜你喜欢
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多