我有一个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调用,反之亦然,看起来第一个调用就是第二个,第二个给出相同的结果。
答案 0 :(得分:4)
如果这是一个准备好的语句,并且这是ORDER BY
子句中提供的绑定值,那么这是有效的,但是......
提供的绑定值不会被解释为SQL文本。也就是说,该值将被视为一个值(如文字字符串)。它不会被视为列名,也不会被视为ASC
或DESC
关键字。
在语句的上下文中,为: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);