【发布时间】:2020-02-11 08:42:17
【问题描述】:
使用 Spring Data JPA 在 Spring Boot 中创建自定义原生 SQL 查询。想用order_num 搜索office_products 表并返回相关的数据行(在现实世界中,有多个具有相同订单号的订单是没有意义的,但在这个例子中,让我们说'是的,所以我们可以返回一个列表)。
使用这个控制器:
@Controller
public class OrderController {
@Autowired
private OrderRepository orderRepository;
@GetMapping("/test")
public String getOrderListByNum(Model model) {
List<OrderEntity> foundByOrderNo = orderRepository.getOrderByOrderNum();
model.addAttribute("foundByOrderNo", foundByOrderNo);
return "test";
}
}
当查询被硬编码为12354 的order_num 值时,我可以成功查询数据库并返回结果,如下所示:
@Repository
public interface OrderRepository extends JpaRepository<OrderEntity, OrderID> {
@Query(value ="SELECT * FROM office_products WHERE order_num=12354", nativeQuery = true)
List<OrderEntity> getOrderByOrderNum();
}
但是,当尝试通过http://localhost:8080/test?orderNum=12354 传递值来使用参数时,如下代码不起作用:
@Repository
public interface OrderRepository extends JpaRepository<OrderEntity, OrderID> {
@Query(value ="SELECT * FROM office_products WHERE order_num = :orderNum", nativeQuery = true)
List<OrderEntity> getOrderByOrderNum();
}
尝试使用参数时,我得到以下错误:
@http://localhost:8080/test?orderNum=12354:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Oct 14 12:07:44 CDT 2019
There was an unexpected error (type=Internal Server Error, status=500).
Named parameter not bound : orderNum; nested exception is org.hibernate.QueryException: Named parameter not bound : orderNum
org.springframework.dao.InvalidDataAccessResourceUsageException: Named parameter not bound : orderNum; nested exception is org.hibernate.QueryException: Named parameter not bound : orderNum
在控制台中:
[ERROR]~2019-10-14-12.07.44.569CDT~~~~~~ o.a.c.c.C.[.[.[.[dispatcherServlet] Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: Named parameter not bound : orderNum; nested exception is org.hibernate.QueryException: Named parameter not bound : orderNum] with root cause
org.hibernate.QueryException: Named parameter not bound : orderNum
最后,将@Param("orderNum") String orderNum 传递给方法List<OrderEntity> getOrderByOrderNum(); 我得到一个新错误:
@http://localhost:8080/test?orderNum=12354:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Oct 14 12:22:11 CDT 2019
There was an unexpected error (type=Internal Server Error, status=500).
Unresolved compilation problem: The method getOrderByOrderNum(String) in the type OrderRepository is not applicable for the arguments ()
java.lang.Error: Unresolved compilation problem:
The method getOrderByOrderNum(String) in the type OrderRepository is not applicable for the arguments ()
知道我在这里缺少什么吗?
更新:
深入挖掘后,我意识到我需要将以下代码添加到我的控制器中,并使用 Shabbir 建议的 JPQL 示例,代码现在可以工作:
@GetMapping("/test")
public String getOrderListByNum(Model model, OrderEntity orderEntity) {
List<OrderEntity> foundByOrderNo = orderRepository.getOrderByOrderNum(orderEntity.getOrderNo());
model.addAttribute("foundByOrderNo", foundByOrderNo);
return "test";
}
更新:
当然还有派生查询解决方案:
@Repository
public interface OrderRepository extends JpaRepository<OrderEntity, OrderID> {
List<OrderEntity> findByOrderNo(String orderNo);
}
【问题讨论】:
-
你的方法没有任何参数。如果调用者不能将任何参数传递给方法,它怎么可能要求订单 42 或订单 54?另外,你为什么要对这么简单的事情使用 SQL 查询?使用 JPQL。甚至是从方法名称自动派生的查询。
-
@JB Nizet 你能给我一个代码示例吗?可以是 SQL 原生查询还是 JPQL?
标签: java sql spring-boot spring-data-jpa