我正在尝试使用命名参数将一些字符串注入查询中。我正在使用spring和hibernateTemplate,而且我对Hibernate还不熟悉。我已经获得了未命名和命名的参数,但似乎当它们彼此相邻时会抛出错误。我在下面的问题中做了类似的示例代码(简化以突出显示手头的问题)。 orderBy包含字段的字符串,orderDirection包含ASC或DESC。
public List<HashMap<String, Object>> exampleList(String orderBy, String orderDirection) {
logger.debug(orderBy);
logger.debug(orderDirection);
final String queryString = "SELECT new map("+
"a.id AS id, "+
"a.name AS name, "+
"a.number AS number ) "+
"FROM Asset a "+
"ORDER BY :orderBy :orderDirection";
String[] parameterNames = {"orderBy", "orderDirection"};
Object[] parameterValues = {orderBy, orderDirection};
List<HashMap<String, Object>> results = (List<HashMap<String, Object>>) hibernateTemplate.find(queryString, parameterNames, parameterValues);
return results;
}
控制台调试我的参数:
DEBUG: com.myOrg.myProject.asset.AssetDAO - a.id
DEBUG: com.myOrg.myProject.asset.AssetDAO - desc
我知道这个查询可以自行运行,因为我已经通过将值直接放入查询字符串来测试它。我知道这是不好的做法,可以让我接触注射,这就是为什么我不这样做。
我得到的错误如下(为了便于阅读,缩短了堆栈跟踪,但这是唯一的错误,我可以根据请求提供完整的堆栈跟踪):
SEVERE: Servlet.service() for servlet dmat3 threw exception
org.hibernate.hql.ast.QuerySyntaxException: unexpected token: : near line 1, column 118 [SELECT new map(a.id AS id, a.name AS name, a.number AS number ) FROM com.gsipt.dmat3.asset.Asset a ORDER BY :orderBy :orderDirection]
at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:31)
at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:24)
at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:59)
at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:258)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:157)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:111)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)
at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:914)
at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:1)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:912)
at com.myOrg.myProject.asset.AssetDAO.exampleList(AssetDAO.java:142)
at com.myOrg.myProject.navigator.NavigatorController.assetGrid(NavigatorController.java:163)
同样,当有单独的参数时,这可以正常工作,但是当它们放在一起时会发生这种情况。可以使用未命名参数重新创建相同的错误,只有“意外令牌”是第二个“?”在查询字符串中。如何将两个名为或未命名的参数放在彼此旁边,这在ORDER BY语句中是有意义的。
谢谢, -Cliff
答案 0 :(得分:1)
您使用的是find
,而不是
findByNamedParams
另请注意,HibernateTemplate文档说
注意:从Hibernate 3.0.1开始, 事务性Hibernate访问代码 也可以在普通的Hibernate中编码 样式。因此,对于新开始 项目,考虑采用 标准的Hibernate3编码风格 数据访问对象,而不是基于 SessionFactory.getCurrentSession()。
答案 1 :(得分:1)
您不能在ORDER BY子句中使用参数(命名或位置)。您只能在WHERE子句中使用它们。
答案 2 :(得分:0)
为什么还需要参数化这些?只要orderBy
和orderDirection
的值不是来自用户输入,您就可以安全地将值连接到查询中。
if orderDirection == Sort.ASC) {
queryString += " ASC";
}
else {
queryString += " DESC";
}
等
答案 3 :(得分:0)
Params用于指定值,而不是用于构建sql语法。只是串起来。