你们有没有人能指出我们如何将order by子句作为命名参数传递给hql
例如:
使用:
select tb from TransportBooking as tb
and TIMESTAMP(tb.bookingDate, tb.bookingTime) >= current_timestamp() order by tb.bookingDate
不起作用:
select tb from TransportBooking as tb
and TIMESTAMP(tb.bookingDate, tb.bookingTime) >= current_timestamp() order by :order
答案 0 :(得分:25)
不支持,输入参数仅允许在WHERE
和HAVING
子句中,并且您不能使用ORDER BY
子句的参数。或者,如果我改写,您不能使用列的参数,只能使用值。所以,要么:
答案 1 :(得分:6)
尝试存储不带order by子句的命名查询,获取查询字符串并在运行时添加order by子句。
Brian Fields在他的博客中解释道: http://brainfields.blogspot.com/2009/08/order-by-in-hibernate-named-queries.html
我已经为我的项目打包了这个想法:
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;
}
答案 2 :(得分:2)
您可能希望将排序字段限制为模型中的排序字段。在我的项目中,我静态地做了这个:
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;
}
在将字符串连接到jpql或hql之前验证DAL上的字段名称将避免sql注入或进一步的问题
答案 3 :(得分:0)
可以这样做
order by CASE :orderBy
WHEN 'pato_id' THEN PATO.id
WHEN 'last_update_dt' THEN PATO.last_update_dt
END desc
你可以通过&#34; pato_id&#34;或&#34; last_update_dt&#34; 在像这样的setString函数中
q.setString("orderBy", "last_update_dt");
or
q.setString("orderBy", "pato_id");
这适用于MS SQL Server,不确定其他人。
答案 4 :(得分:0)
这在MySQL中对我有效:
ORDER BY CASE :orderby WHEN 0 THEN field_x WHEN 1 THEN field_y ELSE field_z END ASC