ppysz
ppysz

Reputation: 390

Parametrised order in spring-data-jdbc

I'm struggling with making order parametrised. The best would be to have

... order by :orderColumn :orderDirection ...

Is it even possible to turn:

    @Query("select * from Document where folderId = :folderId AND documentType = :documentType"
            + " order by created desc limit :limit")
    List<Document> findByFolderIdAndDocumentTypeOrderByWithLimit(Long folderId, String documentType,
                                                                     String orderColumn, Integer limit);

Into:

    @Query("select * from Document where folderId = :folderId AND documentType = :documentType"
            + " order by :orderColumn desc limit :limit")
    List<Document> findByFolderIdAndDocumentTypeOrderByWithLimit(Long folderId, String documentType,
                                                                     String orderColumn, Integer limit);

I'm using spring-data-jdbc 1.1.3.REELASE version. Even doing it for just column name would help me a lot.

Upvotes: 3

Views: 1377

Answers (3)

ppysz
ppysz

Reputation: 390

Until there will be version of spring-data-jdbc (as far as I know 2.X.X.RELEASE) supporting Pagable object I've decided for this particular case use NamedParameterJdbcTemplate and tail my own query. I hope this or other answers here will help someone. Thank you for your help :)

Upvotes: 0

Jens Schauder
Jens Schauder

Reputation: 81990

Replacing a column name with a bind parameter is not possible. This is a limitation of JDBC, and possibly even of SQL.

What you can do is use an expression that evaluates to the value of different columns based on a bind parameter. Something like

... ORDER BY CASE
    WHEN :orderColumn = 'created' THEN created
    WHEN :orderColumn = 'updated' THEN updated
    WHEN :orderColumn = 'deleted' THEN deleted
    ELSE 1
END;

Note that this kind of constructed isn't well supported by query optimisers and therefore will not utilise any index that would otherwise apply.

If you require better support by the optimiser you can always write a custom query that you create dynamically. If you decide to do so, make sure you do not incorporate Strings from untrusted sources in your SQL statement to avoid SQL injection vulnerabilities.

Upvotes: 3

Jens
Jens

Reputation: 69470

Use the PagingAndSortingRepository

  @Query("select * from Document where folderId = :folderId AND documentType = :documentType")
    List<Document> findByFolderIdAndDocumentTypeOrderByWithLimit(Long folderId, String documentType, Pageable pageable);

And call the method:

findByFolderIdAndDocumentTypeOrderByWithLimit(1,"Type", PageRequest.of(0, <limit>, Sort.by(<column name>).descending());

sume examples you can fine here

Upvotes: 2

Related Questions