2012-04-07 3 views
2

Я могу установить переменные значения «где» restrictives:HQL: переменная колонка

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. 
    ... 

UPDATE (рабочий раствор):

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) " 

ответ

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-инъекцию) запросы перед выполнением.

+0

Спасибо, но он говорит: 'Метод replace (String, String) не определен для типа Query'. Я случайно нашел еще один способ в документации - я обнов свой вопрос за несколько минут. – gaffcz

+1

Как уже упоминалось в моем предлагаемом коде, 'query' - это строка, содержащая HQL. – nobeh

+0

Omg, он работает и кажется более чистым, чем мое решение, еще раз спасибо! – gaffcz

5

Вы можете установить имя столбца как часть строки. Для обеспечения безопасности вы можете выполнить SQL-экранирование вручную, но в конце вы можете это сделать.

Чтобы избежать инъекции SQL вы можете использовать commons класс:

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); 
+0

Спасибо, я проверю :-) – gaffcz

Смежные вопросы