我可以为“where”限制条件设置变量值:
Query criteria = session.createQuery(
"select test.col1, test.col2, test.col3
"from Test test " +
"where test.col = :variableValue ");
criteria.setInteger("variableValue", 10);
但是可以像这样设置变量列吗?
String variableColumn = "test.col1";
Query criteria = session.createQuery(
"select test.col1, test.col2, test.col3
"from Test test " +
"where :variableColumn = :variableValue ");
criteria.setInteger("variableValue", 10);
criteria.setString("variableColumn", variableColumn);
结果如下:
Exception in thread "main" Hibernate: select .... where ?=? ...
org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
...
at _test.TestCriteria.main(TestCriteria.java:44)
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting the nvarchar value 'test.col1' to data type int.
...
更新(工作解决方案):
Query criteria = session.createQuery(
"select test.col1, test.col2, test.col3
"from Test test " +
"where (:value1 is null OR test.col1 = :value1) AND
(:value2 is null OR test.col2 = :value2) "
答案 0 :(得分:6)
这在您的应用程序中是否有意义:
String query = "select test.col1, test.col2, test.col3" +
"from Test test " +
"where {columnName} = :variableValue ";
Object variableValue = // retrieve from somewhere
String columnName = // another retrieve from somewhere
query = query.replace("{columnName}", columName);
// Now continue as always
这通常是一个天真的查询构造函数。您可能需要将此想法重构为单独的基于实用程序/实体的类,以便在执行之前优化(例如SQL注入)查询。
答案 1 :(得分:5)
您可以将列名设置为字符串的一部分。为了安全起见,您可以手动执行SQL转义,但最后您可以实现此目的。
为避免SQL注入,您可以使用commons
class:
String escapedVariableColumn = org.apache.commons.lang.StringEscapeUtils.escapeSql(variableColumn);
Query criteria = session.createQuery(
"select test.col1, test.col2, test.col3
"from Test test " +
"where " + escapedVariableColumn + " = :variableValue ");
criteria.setInteger("variableValue", 10);