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.

    注:转载于官方文档

  • 相关阅读:
    php配置GD库
    Linux 安装 Apache2+php5+gd+freetype2
    gd库
    数组和链表的区别
    python 整数中1出现的次数
    python栈--字符串反转,括号匹配
    Linux基础知识
    操作系统
    后台面试问题
    python 面向对象
  • 原文地址:https://www.cnblogs.com/abcdwxc/p/1402435.html
Copyright © 2011-2022 走看看