【问题标题】:Variables in Spring Data JPA native querySpring Data JPA 原生查询中的变量
【发布时间】:2020-02-15 14:57:05
【问题描述】:

使用 Spring Dat JPA,我需要查询我的数据库并根据 startAmtendAmt 的数量返回 OrderEntitys 的范围。我不确定是否应该将这两个变量映射到实体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;


    }

}

【问题讨论】:

    标签: java sql spring-boot spring-data-jpa


    【解决方案1】:

    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);
    

    【讨论】:

      【解决方案2】:

      您可以使用 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&amp;endAmt=2000)中进行这项工作?我正在使用你的第二个例子,原生查询。
      • 1,2 是展示如何在值之间传递从到到的示例。您可以将 1,2 替换为 int 变量。我已经更新了我的答案(第二个例子)。您应该将这些变量从控制器传递到服务和 JPA 存储库
      猜你喜欢
      • 2020-01-11
      • 2019-12-01
      • 1970-01-01
      • 2021-02-13
      • 2017-12-13
      • 2021-11-22
      • 2019-02-20
      • 1970-01-01
      • 2017-05-13
      相关资源
      最近更新 更多