Spring Data JPA 原生查询中的变量

3
使用Spring Data JPA,我需要查询我的数据库并基于金额的startAmt和endAmt返回一系列OrderEntity。我不确定是否应该将这两个变量映射到实体OrderEntity中,作为某种单独类/实体/模型中的字段,还是仅在本地查询中声明它们。也许我应该使用实现EntityManager.createNativeQuery()的服务?我想做的事情类似于:

@Repository
public interface OrderRangeRepository extends JpaRepository<OrderEntity, OrderEntityID> {

        @Query(value = "SELECT * FROM Orders WHERE Amount BETWEEN startAmt AND endAmt;" , nativeQuery=true)
    List<OrderEntity> findOrdersBy(int startAmt, int endAmt);

}

如果我要在一个服务中使用EntityManager.createNativeQuery(),可能会像下面这样:
@Service
public class OrderRangeService {

    @Autowired
    EntityManager entityManager;

    public List<OrderEntity> findAmountsBetween() {

        List<OrderEntity> amountsBetween = entityManager.createNativeQuery("SELECT * FROM Orders WHERE Amount BETWEEN ?1 AND 2?;")
        .setParameter(1, "startAmt")
        .setParameter(2, "endAmt")
        .getResultList();

        return amountsBetween;


    }

}

2个回答

8

您可以使用Spring Data JPA实现此目的,无需定义本地查询。

@Repository
public interface OrderRangeRepository extends JpaRepository<OrderEntity, OrderEntityID> {
    List<OrderEntity> findByAmountBetween(int startAmt, int endAmt);
}

如果您想使用原生查询,请将其更改为

 @Query(value = "SELECT * FROM Orders WHERE Amount BETWEEN :startAmt AND :endAmt" , nativeQuery=true)
List<OrderEntity> findOrdersBy(@Param("startAmt") int startAmt, @Param("endAmt") int endAmt);

您可以通过以下方式在服务中调用查询:
@Service
public class OrderRangeService {

    @Autowired
    OrderRangeRepository orderRangeRepository ;

    public List<OrderEntity> findAmountsBetween(int startAmt, int endAmt) {
        List<OrderEntity> amountsBetween = orderRangeRepository.findByAmountBetween(startAmt, endAmt);
        return amountsBetween;
    }

}

最后,在您的控制器中,您应该自动装配OrderRangeService并调用findAmountsBetween服务方法。

@Autowired
OrderRangeService orderRangeService;

@GetMapping("/amountsFromAndTo")
@ResponseBody
public String getAmounts(@RequestParam int startAmt, @RequestParam int endAmt) {
    List<OrderEntity> orderEntityL = orderRangeService.findAmountsBetween(startAmt, endAmt);
    return orderEntityL.toString();
}

使用findByAmountBetween(1,2)会生成一个查询,查询的结果是介于1和2之间的数字。我想知道如何从HTTP查询字符串中实现这个功能,比如在http://localhost:8080/amountsFromAndTo?startAmt=1000&endAmt=2000中。而且我正在使用你的第二个例子,即原生查询。 - wallwalker
1,2是一个示例,用来展示如何在值之间传递from-to。你可以将1,2替换为整型变量。我已经更新了我的答案(第二个示例)。你应该从控制器将这些变量传递到服务和JPA仓库中。 - Ioannis Barakos

6

1. 命名参数

每个带有 @Param 注解的参数都必须具有与相应的 JPQL 或 SQL 查询参数名称匹配的值字符串。使用命名参数的查询更易于阅读,并且在需要重构查询时,出错的可能性较小。

@Query(value = "SELECT * FROM Orders WHERE Amount BETWEEN :startAmt AND :endAmt;" , nativeQuery=true)
List<OrderEntity> findOrdersBy(@Param("startAmt") int startAmt, @Param("endAmt") int endAmt);

}

2. 索引化查询参数

Spring Data 会按照方法声明中参数出现的顺序将参数传递给查询

@Query(value = "SELECT * FROM Orders WHERE Amount BETWEEN ?1 AND ?2;" , nativeQuery=true)
List<OrderEntity> findOrdersBy(int startAmt, int endAmt);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接