zoukankan      html  css  js  c++  java
  • Named SQL queries

     

    Named SQL queries may be defined in the mapping document and called in exactly the same way as a named HQL query. In this case, we do not need to call AddEntity().

    <sql-query name="persons">
        
    <return alias="person" class="eg.Person"/>
        SELECT person.NAME AS {person.Name},
               person.AGE AS {person.Age},
               person.SEX AS {person.Sex}
        FROM PERSON person
        WHERE person.NAME LIKE :namePattern
    </sql-query>
    IList people = sess.GetNamedQuery("persons")
        .SetString(
    "namePattern", namePattern)
        .SetMaxResults(
    50)
        .List();

    The <return-join> and <load-collection> elements are used to join associations and define queries which initialize collections, respectively.

    <sql-query name="personsWith">
        
    <return alias="person" class="eg.Person"/>
        
    <return-join alias="address" property="person.MailingAddress"/>
        SELECT person.NAME AS {person.Name},
               person.AGE AS {person.Age},
               person.SEX AS {person.Sex},
               adddress.STREET AS {address.Street},
               adddress.CITY AS {address.City},
               adddress.STATE AS {address.State},
               adddress.ZIP AS {address.Zip}
        FROM PERSON person
        JOIN ADDRESS adddress
            ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
        WHERE person.NAME LIKE :namePattern
    </sql-query>

    A named SQL query may return a scalar value. You must declare the column alias and NHibernate type using the <return-scalar> element:

    <sql-query name="mySqlQuery">
        
    <return-scalar column="name" type="String"/>
        
    <return-scalar column="age" type="Int64"/>
        SELECT p.NAME AS name,
               p.AGE AS age,
        FROM PERSON p WHERE p.NAME LIKE 'Hiber%'
    </sql-query>

    You can externalize the resultset mapping informations in a <resultset> element to either reuse them accross several named queries or through the SetResultSetMapping() API.

    <resultset name="personAddress">
        
    <return alias="person" class="eg.Person"/>
        
    <return-join alias="address" property="person.MailingAddress"/>
    </resultset>

    <sql-query name="personsWith" resultset-ref="personAddress">
        SELECT person.NAME AS {person.Name},
               person.AGE AS {person.Age},
               person.SEX AS {person.Sex},
               adddress.STREET AS {address.Street},
               adddress.CITY AS {address.City},
               adddress.STATE AS {address.State},
               adddress.ZIP AS {address.Zip}
        FROM PERSON person
        JOIN ADDRESS adddress
            ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
        WHERE person.NAME LIKE :namePattern
    </sql-query>

    You can alternatively use the resultset mapping information in your .hbm.xml files directly in code.

    IList cats = sess.CreateSQLQuery(
            "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id"
        )
        .SetResultSetMapping("catAndKitten")
        .List();

    14.2.1. Using return-property to explicitly specify column/alias names

    With <return-property> you can explicitly tell NHibernate what column aliases to use, instead of using the {}-syntax to let NHibernate inject its own aliases.

    <sql-query name="mySqlQuery">
        
    <return alias="person" class="eg.Person">
            
    <return-property name="Name" column="myName"/>
            
    <return-property name="Age" column="myAge"/>
            
    <return-property name="Sex" column="mySex"/>
        
    </return>
        SELECT person.NAME AS myName,
               person.AGE AS myAge,
               person.SEX AS mySex,
        FROM PERSON person WHERE person.NAME LIKE :name
    </sql-query>

    <return-property> also works with multiple columns. This solves a limitation with the {}-syntax which can not allow fine grained control of multi-column properties.

    <sql-query name="organizationCurrentEmployments">
        
    <return alias="emp" class="Employment">
            
    <return-property name="Salary">
                
    <return-column name="VALUE"/>
                
    <return-column name="CURRENCY"/>
            
    </return-property>
            
    <return-property name="EndDate" column="myEndDate"/>
        
    </return>
            SELECT EMPLOYEE AS {emp.Employee}, EMPLOYER AS {emp.Employer},
            STARTDATE AS {emp.StartDate}, ENDDATE AS {emp.EndDate},
            REGIONCODE as {emp.RegionCode}, EID AS {emp.Id}, VALUE, CURRENCY
            FROM EMPLOYMENT
            WHERE EMPLOYER = :id AND ENDDATE IS NULL
            ORDER BY STARTDATE ASC
    </sql-query>

    Notice that in this example we used <return-property> in combination with the {}-syntax for injection, allowing users to choose how they want to refer column and properties.

    If your mapping has a discriminator you must use <return-discriminator> to specify the discriminator column.

    14.2.2. Using stored procedures for querying

    NHibernate 1.2 introduces support for queries via stored procedures and functions. Most of the following documentation is equivalent for both. The stored procedure/function must return a resultset to be able to work with NHibernate. An example of such a stored function in MS SQL Server 2000 and higher is as follows:

    CREATE PROCEDURE selectAllEmployments AS
        
    SELECT EMPLOYEE, EMPLOYER, STARTDATE, ENDDATE,
        REGIONCODE, EMPID, VALUE, CURRENCY
        
    FROM EMPLOYMENT

    To use this query in NHibernate you need to map it via a named query.

    <sql-query name="selectAllEmployments_SP">
        
    <return alias="emp" class="Employment">
            
    <return-property name="employee" column="EMPLOYEE"/>
            
    <return-property name="employer" column="EMPLOYER"/>
            
    <return-property name="startDate" column="STARTDATE"/>
            
    <return-property name="endDate" column="ENDDATE"/>
            
    <return-property name="regionCode" column="REGIONCODE"/>
            
    <return-property name="id" column="EID"/>
            
    <return-property name="salary">
                
    <return-column name="VALUE"/>
                
    <return-column name="CURRENCY"/>
            
    </return-property>
        
    </return>
        
    exec selectAllEmployments
    </sql-query>

    Notice that stored procedures currently only return scalars and entities. <return-join> and <load-collection> are not supported.

    14.2.2.1. Rules/limitations for using stored procedures

    To use stored procedures with NHibernate the procedures/functions have to follow some rules. If they do not follow those rules they are not usable with NHibernate. If you still want to use these procedures you have to execute them via session.Connection. The rules are different for each database, since database vendors have different stored procedure semantics/syntax.

    Stored procedure queries can't be paged with SetFirstResult()/SetMaxResults().

    Recommended call form is dependent on your database. For MS SQL Server use exec functionName <parameters>.

    For Oracle the following rules apply:

    • A function must return a result set. The first parameter of a procedure must be an OUT that returns a result set. This is done by using a SYS_REFCURSOR type in Oracle 9 or 10. In Oracle you need to define a REF CURSOR type, see Oracle literature.

    For MS SQL server the following rules apply:

    • The procedure must return a result set. NHibernate will use IDbCommand.ExecuteReader() to obtain the results.

    • If you can enable SET NOCOUNT ON in your procedure it will probably be more efficient, but this is not a requirement.

    注:转载于官方文档

  • 相关阅读:
    SSM之Mybatis整合及使用
    软件设计师08-法律法规与标准化知识
    Spring MVC体系结构
    Spring MVC异常友好展示
    Spring MVC Web.xml配置
    编译型语言解释型语言
    软件设计师07-程序设计语言与语言处理程序基础
    flex布局注意点:
    常见的PC端和移动端表单组件
    js文件的装载和执行
  • 原文地址:https://www.cnblogs.com/abcdwxc/p/1402435.html
Copyright © 2011-2022 走看看