Nhibernate where子句作为参数

Nhibernate where子句作为参数,nhibernate,Nhibernate,在转换遗留应用程序时,我们需要将命名查询转换为nhibernate。问题是where子句正在被设置 这是地图 <resultset name="PersonSet"> <return alias="person" class="Person"> <return-property column="id" name="Id" /> <return-property column="ssn" name="Ssn" /> <return-

在转换遗留应用程序时,我们需要将命名查询转换为nhibernate。问题是where子句正在被设置

这是地图

<resultset name="PersonSet">
<return alias="person" class="Person">
  <return-property column="id" name="Id" />
  <return-property column="ssn" name="Ssn" />
  <return-property column="last_name" name="LastName" />
  <return-property column="first_name" name="FirstName"/>
  <return-property column="middle_name" name="MiddleName" />
</return>
</returnset>

<sql-query name="PersonQuery" resultset-ref="PersonSet" read-only="true" >
  <![CDATA[
  SELECT
  person.ID as {person.Id},
  person.SSN as {person.Ssn},
  person.LAST_NAME as {person.LastName},
  person.MIDDLE_NAME as {person.MiddleName},
  person.FIRST_NAME as {person.FirstName},
  FROM PERSONS as person
  where :value
  ]]>
</sql-query>
错误:

在哪里?];错误代码[];在“@p0”附近预期条件的上下文中指定的非布尔型表达式


我不熟悉这种HibernateTemplate语法,但看起来您是在查询SQL中的原始字段名,而不是别名。试试这个:

String query = "person.LastName = 'Johnson'"; 
或者,也许:

String query = "[person.LastName] = 'Johnson'"; 
或者,可能:

String query = "{person.LastName} = 'Johnson'"; 

取决于在将最终SQL查询发送到服务器之前正在进行何种预处理。

这是因为:value是查询中的绑定变量;您不能简单地将其替换为包含任意字符串(将成为查询的一部分)的字符串,而只能替换为实际值。在您的例子中,值是“person.LAST_NAME='Johnson'”,它实际上是一个字符串,而不是布尔值。布尔值可能是真的,也可能是假的,这两个值对于您试图归档的内容都是无用的


绑定变量或多或少会替换文字,而不是复杂的表达式。

这不起作用,因为您试图将
:value
替换为
“person.LAST\u NAME='Johnson'”
,希望查询变为

SELECT person.ID, person.SSN, person.LAST_NAME, person.MIDDLE_NAME, person.FIRST_NAME
FROM PERSONS as person
where person.LAST_NAME = 'Johnson'
这行不通。您只能动态更换“Johnson”部分,而不能更换整个状况。因此,真正产生的是

SELECT person.ID, person.SSN, person.LAST_NAME, person.MIDDLE_NAME, person.FIRST_NAME
FROM PERSONS as person
where 'person.LAST_NAME = \'Johnson\''
这显然不是WHERE部分的有效条件,因为只有一个文本,但没有列和运算符来比较字段

如果您只需要匹配
person.LAST\u NAME
将xml sql查询重写为

<sql-query name="PersonQuery" resultset-ref="PersonSet" read-only="true" >
  <![CDATA[
  SELECT
  ...
  FROM PERSONS as person
  where person.LAST_NAME = :value
  ]]>
</sql-query>
如果您需要一次按不同的列甚至多个列动态筛选,请使用筛选器。e、 像这样(我对hibernate映射文件做了一些假设)

如果您还需要更多的动态查询(例如,甚至更改运算符(=,!=,如,>),
<sql-query name="PersonQuery" resultset-ref="PersonSet" read-only="true" >
  <![CDATA[
  SELECT
  ...
  FROM PERSONS as person
  where person.LAST_NAME = :value
  ]]>
</sql-query>
String query = "Johnson";
<hibernate-mapping>
  ...
  <class name="Person">
    <id name="id" type="int">
      <generator class="increment"/>
    </id>
    ...
    <filter name="ssnFilter" condition="ssn = :ssnValue"/>
    <filter name="lastNameFilter" condition="lastName = :lastNameValue"/>
    <filter name="firstNameFilter" condition="firstName = :firstNameValue"/>
    <filter name="middleNameFilter" condition="middleName = :middleNameValue"/>
  </class>
  ...
  <sql-query name="PersonQuery" resultset-ref="PersonSet" read-only="true" >
  ...
    FROM PERSONS as person
  ]]>
  </sql-query>
  <!-- note the missing WHERE clause in the PersonQuery -->
  ...
  <filter-def name="ssnFilter">
    <filter-param name="ssnValue" type="int"/>
  </filter-def>
  <filter-def name="lastNameFilter">
    <filter-param name="lastNameValue" type="string"/>
  </filter-def>
  <filter-def name="middleNameFilter">
    <filter-param name="midlleNameValue" type="string"/>
  </filter-def>
  <filter-def name="firstNameFilter">
    <filter-param name="firstNameValue" type="string"/>
  </filter-def>
</hibernate-mapping>
String lastName = "Johnson";
String firstName = "Joe";

//give me all persons first
HibernateTemplate.FindByNamedQuery("PersonQuery");

//just give me persons WHERE FIRST_NAME = "Joe" AND LAST_NAME = "Johnson"
Filter filter = HibernateTemplate.enableFilter("firstNameFilter");
filter.setParameter("firstNameValue", firstName);
filter = HibernateTemplate.enableFilter("lastNameFilter");
filter.setParameter("lastNameValue", lastName);
HibernateTemplate.FindByNamedQuery("PersonQuery");

//oh wait. Now I just want all Johnsons
HibernateTemplate.disableFilter("firstNameFilter");
HibernateTemplate.FindByNamedQuery("PersonQuery");

//now again give me all persons
HibernateTemplate.disableFilter("lastNameFilter");
HibernateTemplate.FindByNamedQuery("PersonQuery");