将控制器端点映射到Spring JPA层

huangapple go评论91阅读模式
英文:

Mapping controller endpoints to Spring JPA layer

问题

我已将您提供的内容翻译如下:

我已编写此请求映射,以通过可选的请求参数ticketType和ticketStatus访问按其id访问票据:

@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) {
    // 方法体...
}

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

还是更新控制器以根据查询选择要实现的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(tickets.size() == 0){
        return ResponseEntity.ok("No tickets found");
    } else {
        return ResponseEntity.ok(tickets);
    }
}

JPA存储库将进一步扩展以根据许多其他参数(例如ticketType、ticketDescription)进行筛选。我只是提到这一点,因为如果需要检查哪个参数为null,然后选择相关的JPA查询,我的控制器逻辑将变得非常复杂。

英文:

I've written this request mapping to access a ticket by it's id with the optional request parameters ticketType & ticketStatus :

@GetMapping(path = &quot;/tickets/{ticketId}&quot;)
   @ResponseStatus(value = HttpStatus.OK)
    public ResponseEntity&lt;List&lt;TicketResponse&gt;&gt; getTicketsById(@PathVariable(&quot;ticketId&quot;) final Long ticketId, @RequestParam(&quot;ticketType&quot;) final String ticketType, @RequestParam(&quot;ticketStatus&quot;) final String ticketStatus)

Currently the repository contains methods for returning based on either the ticketId or the ticketState :

    @Repository
    public interface TicketRepository extends JpaRepository&lt;TicketEntity, Long&gt; {
    
Stream&lt;TicketEntity&gt; findByTicketIdAndTicketState(@Param(&quot;ticketId&quot;) Long ticketId);

Stream&lt;TicketEntity&gt; findByTicketIdAndTicketState(@Param(&quot;ticketId&quot;) Long ticketId, @Param(&quot;ticketState&quot;) String ticketState);

    }

How should these endpoints be exposed at the controller layer ?

Currently the endpoint is:

@GetMapping(path = &quot;/{ticketId}&quot;)
    @ResponseStatus(value = HttpStatus.OK)
    public ResponseEntity&lt;List&lt;TicketResponse&gt;&gt; getTicketsByTicketId(
            @PathVariable(&quot;productId&quot;) final Long ticketId, @RequestParam(name = &quot;ticketState&quot;, required=false) final String ticketState) {

        final List&lt;TicketResponse&gt; ticketsByTicketId = ticketService.getTicketsByTicketId(ticketId);

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

    }

Should I add a new endpoint? :

Or update the controller to select which JPA repository method to implement depending on the query ?:

@GetMapping(path = &quot;/{ticketId}&quot;)
    @ResponseStatus(value = HttpStatus.OK)
    public ResponseEntity&lt;List&lt;TicketResponse&gt;&gt; getTicketsByTicketId(
            @PathVariable(&quot;productId&quot;) final Long ticketId, @RequestParam(name = &quot;ticketState&quot;, required=false) final String ticketState) {

List&lt;TicketResponse&gt; tickets = null;
 
if(ticketState == null) {
        tickets = ticketService.getTicketsByTicketId(ticketId);
}
else{
tickets = ticketService.getTicketsByTicketIdAndTicketState(ticketId, ticketState);
}

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

    }

The JPA repository will be extended further to filter based on many more parameters such as ticketType, ticketDescription . I just mention this as my controller logic will get very complicated if is required to check which parameter is null and the select the relevant JPA query.

答案1

得分: 0

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

一个关于JPA规范的好文章

英文:

Using Spring Data JPA Specification this map filtering problem can be solved.
Complex queries can be build using the Criteria API depends on the filtering parameter.

A good article about JPA Specification

huangapple
  • 本文由 发表于 2020年4月5日 19:39:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/61041979.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定