Hibernate nazwanej kolejności zapytań według parametru
Witam czy ktoś może mi wskazać, jak możemy przekazać klauzulę order by jako nazwany parametr do hql
Ex:
Działa:
select tb from TransportBooking as tb
and TIMESTAMP(tb.bookingDate, tb.bookingTime) >= current_timestamp() order by tb.bookingDate
Nie działa:
select tb from TransportBooking as tb
and TIMESTAMP(tb.bookingDate, tb.bookingTime) >= current_timestamp() order by :order
4 answers
Nie jest obsługiwane, parametry wejściowe są dozwolone tylko w klauzulach WHERE
i HAVING
i nie można używać parametrów dla klauzuli ORDER BY
. Albo jeśli przeformułuję, nie możesz używać parametrów dla kolumn, tylko wartości. Więc albo:
- mieć jak najwięcej nazwanych zapytań, jak to możliwe kolejność sortowania
- połącz łańcuch rozkazujący z łańcuchem zapytania
- Use criteria queries
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-08 06:10:00
Spróbuj zapisać nazwane zapytanie bez klauzuli order by, pobierając łańcuch zapytania i dodając fragmenty klauzuli order by w czasie wykonywania.
Brian Fields wyjaśnił to na swoim blogu: http://brainfields.blogspot.com/2009/08/order-by-in-hibernate-named-queries.htmlZapakowałem pomysł do mojego projektu:
private static final Pattern badQueryPattern = Pattern.compile("[^\\p{ASCII}]*");
public static String getNamedQueryString(EntityManager em, String queryName) throws SQLException {
Query tmpQuery = em.createNamedQuery(queryName);
SQLQuery sqlQuery = tmpQuery.unwrap(SQLQuery.class);
String queryString = sqlQuery.getQueryString();
if (badQueryPattern.matcher(queryString).matches()) {
throw new SQLException("Bad query string.");
}
return queryString;
}
public static Query getNamedQueryOrderedBy(EntityManager em, String queryName, Map<String, Boolean> columnNames) throws SQLException {
StringBuilder sb = new StringBuilder();
sb.append(ORDER_BY_CLAUSE_START);
int limit = columnNames.size();
int i = 0;
for (String columnName: columnNames.keySet()) {
sb.append(columnName);
if (columnNames.get(columnName))
sb.append(" ASC");
else
sb.append(" DESC");
if (i != (limit - 1)) {
sb.append(", \n");
}
}
Query jpaQuery = em.createNativeQuery( getNamedQueryString(em, queryName)
+ sb.toString()
);
return jpaQuery;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-09 21:58:27
Możesz ograniczyć pole sortowania do tych, które masz w swoim modelu. W moim projekcie zrobiłem to statycznie:
public static boolean isColumnName(Object domain, String columnName) {
Field[] fields = domain.getClass().getDeclaredFields();
for (Field field : fields) {
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation instanceof Column) {
Column column = (Column) annotation;
String foundColumnName;
if (column.name() != null && !column.name().isEmpty()) {
foundColumnName = column.name();
} else {
foundColumnName = field.getName();
}
if (columnName.toUpperCase().equals(
foundColumnName.toUpperCase())) {
return true;
}
}
}
}
return false;
}
Sprawdzanie nazwy pola na Tobie DAL przed concat łańcuch do jpql lub hql unikniesz SQL injection lub dalszych problemów
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-04 19:16:55
Można to zrobić tak
order by CASE :orderBy
WHEN 'pato_id' THEN PATO.id
WHEN 'last_update_dt' THEN PATO.last_update_dt
END desc
I możesz podać "pato_id" lub " last_update_dt" w funkcji setString jak Ta
q.setString("orderBy", "last_update_dt");
or
q.setString("orderBy", "pato_id");
To działa z MS SQL Server, nie jestem pewien co do innych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-26 20:15:55