存储库 - 在本机查询中的顺序无效

时间:2014-09-26 21:30:54

标签: sql spring postgresql jpa native

我有一个spring数据JPA存储库(在postgres数据库中),有时我需要使用nativeQuery = true选项来使用本机查询。

然而,在我目前的情况下,我需要传递一个订单字段,我这样做:

电话..

targetStatusHistoryRepository.findSirenAlarmTimeActivation([uuid,uuid2],"activation_name DESC", 0, 10)

..回购方法

@Query(
        nativeQuery = true,
        value = """select
                     a.name as activation_name,
                     min(transition_from_active_in_millis),
                     max(transition_from_active_in_millis),
                     avg(transition_from_active_in_millis) from target_status_history t, activation_scenario a
                     where t.activation_uuid=a.activation_scenario_id and t.transition_from_active_in_millis > 0 and t.activation_uuid in (:activationUUIDs) group by a.name,t.activation_uuid
                     order by :orderClause offset :offset limit :limit """
)
List<Object[]> findSirenAlarmTimeActivation(@Param("activationUUIDs") List<UUID> activationUUIDs,
                                                              @Param("orderClause") String orderClause, @Param("offset") int offset, @Param("limit") int limit )

我用DESC写了一个单元测试,然后用ASC调用,反之亦然,看起来第一个调用就是第二个,第二个给出相同的结果。

4 个答案:

答案 0 :(得分:4)

如果这是一个准备好的语句,并且这是ORDER BY子句中提供的绑定值,那么这是有效的,但是......

提供的绑定值不会被解释为SQL文本。也就是说,该值将被视为一个值(如文字字符串)。它不会被视为列名,也不会被视为ASCDESC关键字。

在语句的上下文中,为:orderClause绑定占位符提供值,这与您编写ORDER BY 'some literal'时的效果相同。

这根本就没有对行进行任何排序。

(至少在我用于DB2,Teradata,Oracle,SQL Server,MySQL和MariaDB的每个SQL客户端库中都是如此(JDBC,Perl DBI,ODBC,Pro / C等)

(MyBatis提供了一种方便的机制,可以在SQL文本中进行变量替换,在准备之前动态更改SQL文本,但是在语句准备之前处理这些替换,并且不要在语句中变成绑定占位符。)

可以在ORDER BY子句中使用一些精心设计的表达式获得一些“动态”排序。例如,我们可以使用我们的静态SQL文本:

  ORDER BY CASE WHEN :sort_param = 'name ASC'  THEN activation_name END ASC
         , CASE WHEN :sort_param = 'name DESC' THEN activation_name END DESC

(这里的SQL文本不是动态的,它实际上是静态的,就像我们写的一样。

 ORDER BY expr1 ASC
        , expr1 DESC

“技巧”是ORDER BY子句中的表达式有条件地从每一行返回某个列的值,或者它们返回一个文字(在上面的示例中,文字为NULL),具体取决于值一个绑定值,在执行时计算。

净效应是我们可以“动态地”获得以下任何一种效果:

 ORDER BY activation_name ASC, NULL DESC

 ORDER BY NULL ASC, activation_name DESC

 ORDER BY NULL ASC, NULL DESC

取决于我们为:sort_param占位符提供的值。

答案 1 :(得分:0)

您可以使用SpEL语言进行分页。 Sort中的Pageable对象将用于在请求结尾附加" order by "Here就是一个例子。

答案 2 :(得分:0)

使用createNativeQuery并将按值作为字符串直接将订单追加到查询中,而不是使用setParameter()。对我来说很好。

答案 3 :(得分:0)

我在 Spring Boot 中使用本机查询时遇到了同样的问题,我发现的方法是:

1- 创建可分页:

Pageable pageable = PageRequest.of(numPage, sizePage, Sort.by(direction , nameField));

2- 在查询中添加“ORDER BY true”,例如:

@Query(value = " SELECT  * " +
            "FROM articulos a   " +
            "WHERE " +            
            "AND a.id = :id" +           
            "ORDER BY TRUE",
        countQuery = " SELECT  * " +
            "FROM articulos a   " +
            "WHERE " +            
            "AND a.id = :id" +           
            "ORDER BY TRUE"
        , nativeQuery = true)
    Page<PrecioArticuloVO> obtenerPreciosPorCategoriaProveedor(@Param("id")Long id,Pageable pagina);