I am using sql query
like
String query = "Select max(case when UPPER(key)='firstname' then value end) as firstNameName, , ... order by "+orderBy;
result = em.createNativeQuery(query).getResultList();
em.close();
for some reason i would have to use dynamic +orderBy
. Where orderBy =firstname ASC, lastname DESC
etc. Tried using .setParameter(1, orderedBy)
but in this case i am not getting expected ordered results.
For avoiding sql injection threats you firstly need to remove appending parameters to your query. When you're appending parameters in your app, the atacker can hijack your sql code (with apostrophes and other means for example)
For example:
If your query is "select * from table where name="+id
The attacker can pass to the field values such as: 'John' or 1=1;
->sees all your records in this table
Or even 'John' or 1=1;Delete all from users;'
-> deleting all entries from users table.
Hijacking queries can be avoided via mechanisms such as input sanitization, input whitelisting/blacklisting(removing unwanted characters from the input/ defining a list of allowed or unnalowed characters). Most modern framerowks such as JDBC/JPA/Hibernate can offer protection from this threat.
With all this stated we should take into consideration the following scenarios:
Considering sql where parameters:
JDBC for example offers prepared statements, where you define a variable in your sql, and the framework replaces it
In your case a JPA implementation(Hibernate) also has mechanisms for avoiding this threat, also via parameterized queries and positional paramaters:
Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = ?1");
q.setParameter(1, "test");
Query q = em.createQuery("SELECT count(*) FROM mytable where username = :username");
q.setParameter("username", "test");
Considering orderBy parameters:
CriteriaQuery
/spring Specifications
CriteriaBuilder cb = this.entityManager
.getCriteriaBuilder();
CriteriaQuery<RESULT> criteria = cb.createQuery(RESULT.class);
Root<RESULT> root = criteria.from(RESULT.class);
return this.entityManager.createQuery(
criteria.select(root).orderBy(cb.asc(root.get("ORDER_BY_FIELD"))))
.getResultList();
More on criteriaQueries usage and config here
orderBy
via spring specific Sort
parameter built beforehand(using the spring-data library)Sort sort = Sort.by(Sort.Direction.ASC, "criteria");
em.createQuery(QueryUtils.applySorting(yourSqlQuery_withoutSorting,sort));
You can achieve the same result with less boiler plate code(without injecting an entityManager and creating a nativeQuery) by just annotating a method with a @Query
annotation:
@Query("select u from User u where u.lastname like ?1%")
List<User> findByAndSort(String lastname, Sort sort);
Note:
Native vs non-native(jpql): JOQL queries are independent of the database vendor(MySQL,PostGres,Oracle,DB2), nativeQueries usages are more focused when you need to use a database specific functionalities which differes accross vendors. For a brief example jpql can not support native [With]
2 clause PLSQL standard functions
Regarding your edit:
You can try to apply the following sql trick for dynamic ordering:
SELECT param1, param2 ...
FROM ...
ORDER BY case when :sortParam='name asc' then name asc END
case when :sortParam='name desc' then name desc END
....
else 0
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.