querysql.html
来自「是一个中文的Hibernate库文档」· HTML 代码 · 共 244 行 · 第 1/2 页
HTML
244 行
<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> { ? = call selectAllEmployments() }</sql-query></pre><p> </p><p> 注意存储过程当前仅仅返回标量和实体.现在不支持<tt class="literal"><return-join></tt>和<tt class="literal"><load-collection></tt> </p><div class="sect3" lang="zh-cn"><div class="titlepage"><div><div><h4 class="title"><a name="querysql-limits-storedprocedures"></a>17.3.2.1. 使用存储过程的规则和限制</h4></div></div><div></div></div><p> 为了在Hibernate中使用存储过程,你必须遵循一些规则.不遵循这些规则的存储过程将不可用.如果你仍然想要使用他们, 你必须通过<tt class="literal">session.connection()</tt>来执行他们.这些规则针对于不同的数据库.因为数据库 提供商有各种不同的存储过程语法和语义. </p><p> 对存储过程进行的查询无法使用<tt class="literal">setFirstResult()/setMaxResults()</tt>进行分页。 </p><p> 对于Oracle有如下规则: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 存储过程必须返回一个结果集.它通过返回SYS_REFCURSOR实现(在Oracle9或10),在Oracle里你需要定义一个<tt class="literal">REF CURSOR</tt> 类型 </p></li><li><p> 推荐的格式是 <tt class="literal">{ ? = call procName(<parameters>) }</tt> 或 <tt class="literal">{ ? = call procName }</tt>(这更像是Oracle规则而不是Hibernate规则) </p></li></ul></div><p> 对于Sybase或者MS SQL server有如下规则: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 存储过程必须返回一个结果集。.注意这些servers可能返回多个结果集以及更新的数目.Hibernate将取出第一条结果集作为它的返回值, 其他将被丢弃。 </p></li><li><p> 如果你能够在存储过程里设定<tt class="literal">SET NOCOUNT ON</tt>,这可能会效率更高,但这不是必需的。 </p></li></ul></div></div></div></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="querysql-cud"></a>17.4. 定制SQL用来create,update和delete</h2></div></div><div></div></div><p> Hibernate3能够使用定制的SQL语句来执行create,update和delete操作。在Hibernate中,持久化的类和集合已经 包含了一套配置期产生的语句(insertsql, deletesql, updatesql等等),这些映射标记 <tt class="literal"><sql-insert></tt>, <tt class="literal"><sql-delete></tt>, and <tt class="literal"><sql-update></tt>重载了 这些语句。 </p><pre class="programlisting"><class name="Person"> <id name="id"> <generator class="increment"/> </id> <property name="name" not-null="true"/> <sql-insert>INSERT INTO PERSON (NAME, ID) VALUES ( UPPER(?), ? )</sql-insert> <sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE ID=?</sql-update> <sql-delete>DELETE FROM PERSON WHERE ID=?</sql-delete></class></pre><p> 这些SQL直接在你的数据库里执行,所以你可以自由的使用你喜欢的任意语法。但如果你使用数据库特定的语法, 这当然会降低你映射的可移植性。 </p><p> 如果设定<tt class="literal">callable</tt>,则能够支持存储过程了。 </p><pre class="programlisting"><class name="Person"> <id name="id"> <generator class="increment"/> </id> <property name="name" not-null="true"/> <sql-insert callable="true">{call createPerson (?, ?)}</sql-insert> <sql-delete callable="true">{? = call deletePerson (?)}</sql-delete> <sql-update callable="true">{? = call updatePerson (?, ?)}</sql-update></class></pre><p> 参数的位置顺序是非常重要的,他们必须和Hibernate所期待的顺序相同。 </p><p> 你能够通过设定日志调试级别为<tt class="literal">org.hiberante.persister.entity</tt>,来查看Hibernate所期待的顺序。在这个级别下, Hibernate将会打印出create,update和delete实体的静态SQL。如果想看到预想中的顺序。记得不要将定制SQL包含在映射文件里, 因为他们会重载Hibernate生成的静态SQL。 </p><p> 在大多数情况下(最好这么做),存储过程需要返回插入/更新/删除的行数,因为Hibernate对语句的成功执行有些运行时的检查。 Hibernate常会把进行CUD操作的语句的第一个参数注册为一个数值型输出参数。 </p><pre class="programlisting">CREATE OR REPLACE FUNCTION updatePerson (uid IN NUMBER, uname IN VARCHAR2) RETURN NUMBER ISBEGIN update PERSON set NAME = uname, where ID = uid; return SQL%ROWCOUNT;END updatePerson;</pre></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="querysql-load"></a>17.5. 定制装载SQL</h2></div></div><div></div></div><p> 你可能需要声明你自己的SQL(或HQL)来装载实体 </p><pre class="programlisting"><sql-query name="person"> <return alias="p" class="Person" lock-mode="upgrade"/> SELECT NAME AS {p.name}, ID AS {p.id} FROM PERSON WHERE ID=? FOR UPDATE</sql-query></pre><p> 这只是一个前面讨论过的命名查询声明,你可以在类映射里引用这个命名查询。 </p><pre class="programlisting"><class name="Person"> <id name="id"> <generator class="increment"/> </id> <property name="name" not-null="true"/> <loader query-ref="person"/></class></pre><p> 这也可以用于存储过程 </p><p> TODO: 未完成的例子 </p><pre class="programlisting"><sql-query name="organizationEmployments"> <load-collection alias="empcol" role="Organization.employments"/> SELECT {empcol.*} FROM EMPLOYMENT empcol WHERE EMPLOYER = :id ORDER BY STARTDATE ASC, EMPLOYEE ASC</sql-query><sql-query name="organizationCurrentEmployments"> <return alias="emp" class="Employment"/> <synchronize table="EMPLOYMENT"/> SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer}, STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate}, REGIONCODE as {emp.regionCode}, ID AS {emp.id} FROM EMPLOYMENT WHERE EMPLOYER = :id AND ENDDATE IS NULL ORDER BY STARTDATE ASC</sql-query></pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="querycriteria.html">上一页</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">上一级</a></td><td width="40%" align="right"> <a accesskey="n" href="filters.html">下一页</a></td></tr><tr><td width="40%" align="left" valign="top">第 16 章 条件查询(Criteria Queries) </td><td width="20%" align="center"><a accesskey="h" href="index.html">起始页</a></td><td width="40%" align="right" valign="top"> 第 18 章 过滤数据</td></tr></table></div></body></html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?