📄 querysql.html
字号:
<html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>第 17 章 Native SQL查询</title><link rel="stylesheet" href="../shared/css/html.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.65.1"><link rel="home" href="index.html" title="HIBERNATE - 符合Java习惯的关系数据库持久化"><link rel="up" href="index.html" title="HIBERNATE - 符合Java习惯的关系数据库持久化"><link rel="previous" href="querycriteria.html" title="第 16 章 
 条件查询(Criteria Queries)
 "><link rel="next" href="filters.html" title="第 18 章 过滤数据"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">第 17 章 Native SQL查询</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="querycriteria.html">上一页</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="filters.html">下一页</a></td></tr></table><hr></div><div class="chapter" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title"><a name="querysql"></a>第 17 章 Native SQL查询</h2></div></div><div></div></div><p> 你也可以使用你的数据库的Native SQL语言来查询数据。这对你在要使用数据库的某些特性的时候(比如说在查询提示或者Oracle中的 <tt class="literal">CONNECT</tt>关键字),这是非常有用的。这就能够扫清你把原来直接使用SQL/JDBC 的程序迁移到基于 Hibernate应用的道路上的障碍。 </p><p> Hibernate3允许你使用手写的sql来完成所有的create,update,delete,和load操作(包括存储过程) </p><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="querysql-creating"></a>17.1. 创建一个基于SQL的<tt class="literal">Query</tt></h2></div></div><div></div></div><p> SQL查询是通过<tt class="literal">SQLQuery</tt>接口来控制的,它是通过调用Session.createSQLQuery()方法来获得 </p><pre class="programlisting">List cats = sess.createSQLQuery("select {cat.*} from cats cat") .addEntity("cat", Cat.class); .setMaxResults(50); .list();</pre><p> 这个查询指定了: </p><div class="itemizedlist"><ul type="disc"><li><p> SQL查询语句,它带一个占位符,可以让Hibernate使用字段的别名. </p></li><li><p> 查询返回的实体,和它的SQL表的别名. </p></li></ul></div><p> <tt class="literal">addEntity()</tt>方法将SQL表的别名和实体类联系起来,并且确定查询结果集的形态。 </p><p> <tt class="literal">addJoin()</tt>方法可以被用于载入其他的实体和集合的关联,TODO:examples! </p><p> 原生的SQL查询可能返回一个简单的标量值或者一个标量和实体的结合体。 </p><pre class="programlisting">Double max = (Double) sess.createSQLQuery("select max(cat.weight) as maxWeight from cats cat") .addScalar("maxWeight", Hibernate.DOUBLE); .uniqueResult();</pre></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="querysql-aliasreferences"></a>17.2. 别名和属性引用</h2></div></div><div></div></div><p> 上面使用的<tt class="literal">{cat.*}</tt>标记是 "所有属性" 的简写.你可以显式地列出需要的字段,但是你必须让Hibernate 为每一个属性注入字段的别名.这些字段的站位符是以字段别名为前导,再加上属性名.在下面的例子里,我们从一个其他的表(<tt class="literal">cat_log</tt>) 中获取<tt class="literal">Cat</tt>对象,而非Cat对象原本在映射元数据中声明的表.注意我们甚至在where子句中也可以使用属性别名. 对于命名查询,{}语法并不是必需的.你可以在<a href="querysql.html#querysql-namedqueries" title="17.3. 命名SQL查询">第 17.3 节 “命名SQL查询”</a>得到更多的细节. </p><pre class="programlisting">String sql = "select cat.originalId as {cat.id}, " + "cat.mateid as {cat.mate}, cat.sex as {cat.sex}, " + "cat.weight*10 as {cat.weight}, cat.name as {cat.name} " + "from cat_log cat where {cat.mate} = :catId" List loggedCats = sess.createSQLQuery(sql) .addEntity("cat", Cat.class) .setLong("catId", catId) .list();</pre><p> <span class="emphasis"><em>注意:</em></span>如果你明确地列出了每个属性,你必须包含这个类<span class="emphasis"><em>和它的子类的属性</em></span>! <span class="emphasis"><em>and its subclasses</em></span>! </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="querysql-namedqueries"></a>17.3. 命名SQL查询</h2></div></div><div></div></div><p> 可以在映射文档中定义查询的名字,然后就可以象调用一个命名的HQL查询一样直接调用命名SQL查询.在这种情况下,我们<span class="emphasis"><em>不</em></span> 需要调用<tt class="literal">addEntity()</tt>方法. </p><pre class="programlisting"><sql-query name="mySqlQuery"> <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 'Hiber%'</sql-query></pre><pre class="programlisting">List people = sess.getNamedQuery("mySqlQuery") .setMaxResults(50) .list();</pre><p> 一个命名查询可能会返回一个标量值.你必须使用<tt class="literal"><return-scalar></tt>元素来指定字段的别名和 Hibernate类型 </p><pre class="programlisting"><sql-query name="mySqlQuery"> <return-scalar column="name" type="string"/> <return-scalar column="age" type="long"/> SELECT p.NAME AS name, p.AGE AS age, FROM PERSON p WHERE p.NAME LIKE 'Hiber%'</sql-query></pre><p> <tt class="literal"><return-join></tt>和<tt class="literal"><load-collection></tt>元素分别用作 外连接和定义那些初始化集合的查询 </p><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="propertyresults"></a>17.3.1. 使用return-property来明确地指定字段/别名</h3></div></div><div></div></div><p> 使用<tt class="literal"><return-property></tt>你可以明确的告诉Hibernate使用哪些字段,这和使用<tt class="literal">{}</tt>-语法 来让Hibernate注入它自己的别名是相反的. </p><pre class="programlisting"><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></pre><tt class="literal"><return-property></tt>也可用于多个字段,它解决了使用<tt class="literal">{}</tt>-语法不能细粒度控制多个字段的限制 <pre class="programlisting"><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></pre><p> 注意在这个例子中,我们使用了<tt class="literal"><return-property></tt>结合<tt class="literal">{}</tt>的注入语法. 允许用户来选择如何引用字段以及属性. </p><p> 如果你映射一个识别器(discriminator),你必须使用<return-discriminator>来指定识别器字段 </p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="sp_query"></a>17.3.2. 使用存储过程来查询</h3></div></div><div></div></div><p> Hibernate 3引入了对存储过程查询的支持. 存储过程必须返回一个结果集,作为Hibernate能够使用的第一个外部参数. 下面是一个Oracle9和更高版本的存储过程例子. </p><pre class="programlisting">CREATE OR REPLACE FUNCTION selectAllEmployments RETURN SYS_REFCURSOR AS st_cursor SYS_REFCURSOR; BEGIN OPEN st_cursor FOR SELECT EMPLOYEE, EMPLOYER, STARTDATE, ENDDATE, REGIONCODE, EID, VALUE, CURRENCY FROM EMPLOYMENT; RETURN st_cursor; END;</pre><p> 在Hibernate里要要使用这个查询,你需要通过命名查询来映射它. </p><pre class="programlisting"><sql-query name="selectAllEmployees_SP" callable="true">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -