简体   繁体   English

Spring 数据 JPA:使用多个@PathVariable 检索数据

[英]Spring Data JPA : retrieve data with multiple @PathVariable

I am trying to retrieve a user's particular order.我正在尝试检索用户的特定订单。


This is how I retrieve the user's order s in my OrderController这就是我在 OrderController 中检索用户订单方式

@GetMapping("/{id}/orders")
public List<Order> findAll(@PathVariable Long id) throws UserNotFoundException {
    Optional<User> existingUser = this.userRepository.findById(id);

    if (existingUser.isEmpty()) {
        throw new UserNotFoundException("User not found");
    }

    return existingUser.get().getOrders();
}

With the RequestMapping使用 RequestMapping

@RestController
@RequestMapping("/api/users")
public class OrderController {(...)}

This is the OneToMany relationship这是 OneToMany 关系

User Entity用户实体

// ONE TO MANY
@OneToMany(mappedBy = "user")
private List<Order> orders;

Order Entity订单实体

// MANY TO ONE
@ManyToOne(fetch = FetchType.LAZY)
@JsonIgnore
private User user;

The UserRepository and OrderRepository interface, both extend JpaRepository UserRepository 和 OrderRepository 接口,都扩展了 JpaRepository


I do manage to retrieve all the user's orders through Postman我确实设法通过 Postman 检索所有用户的订单

在此处输入图像描述


I am now wondering, how can I retrieve a user's particular order?我现在想知道,如何检索用户的特定订单?

So for instance, as shown in the image let's say I would only like to retrieve the order with the id of 2, in this particular address:例如,如图所示,假设我只想在这个特定地址中检索 id 为 2 的订单:

http://localhost:8070/api/users/1/orders/2

How can I make it please?请问我该怎么做?

Create an endpoint with创建一个端点

@GetMapping("/{id}/orders/{orderId}")

and return the particular order.并返回特定的订单。

Create an OrderRepository and simply create the创建一个 OrderRepository 并简单地创建

public Order findByIdAndUserId(long orderId,long userId);

interface method for retrieving the given one.用于检索给定的接口方法。

Just a remark: you should validate that the given user is the same as the logged in one.只是一句话:您应该验证给定的用户与登录的用户相同。 What happen if I send a request to the backend, where I rewrite the user id to someone else's id?如果我向后端发送请求,我将用户 ID 重写为其他人的 ID,会发生什么情况?

try this,尝试这个,

    @GetMapping("/{userId}/orders/{orderId}")
    public Order findAll(@PathVariable Long userId, @PathVariable Long orderId) throws Exception {
        //your code
    }

Obviously you should had a Get mapping:显然你应该有一个 Get 映射:

@GetMapping("/{userId}/orders/{orderId}")
public List<Order> findAll(@PathVariable Long userId, @PathVariable Long orderId) throws UserNotFoundException {
    ...
}

And for the requesting, you have three options:对于请求,您有三个选项:

  1. Call you this.userRepository.findById(id) and filter after your order.打电话给你this.userRepository.findById(id)并在你的订单后过滤。
  2. Create an OrderRepository to limit the request to the order table.创建一个 OrderRepository 以限制对订单表的请求。 But you need to have a reference to the user and you will probably not improve any performance.但是您需要参考用户,您可能不会提高任何性能。 I would not advise that.我不建议这样做。
  3. Add a query in your order repository to query the orderId for the userId:在您的订单存储库中添加查询以查询 userId 的 orderId:

@Repository
public interface UserRepository extends JpaRepository<.., ..> {
    @Query("select ... from User user join user.orders ... where ...user = :userId and order = :orderId")
    Order getUserOrder(@Param("userId") String userId, @Param("orderId") String orderId);
}

Anyway, You should create a service and inject it in the controller to encapsulate the search/filtering complexity and let you endpoints code clean ( @Autowired private OrderService orderService ):无论如何,您应该创建一个服务并将其注入 controller 以封装搜索/过滤复杂性并让您的端点代码干净( @Autowired private OrderService orderService ):

@RestController
@RequestMapping("/api/users")
public class OrderController {
    @Autowired
    private OrderService orderService;
}

and:和:

@Service
public class OrderService {

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM