📄 objectstate.html
字号:
sess.flush(); //force the SQL INSERTsess.refresh(cat); //re-read the state (after the trigger executes)</pre><p> 此处通常会出现一个重要问题: Hibernate会从数据库中装载多少东西?会执行多少条相应的SQL<tt class="literal">SELECT</tt>语句? 这取决于<span class="emphasis"><em>抓取策略(fetching strategy)</em></span>,会在<a href="performance.html#performance-fetching" title="20.1. 
 
 抓取策略(Fetching strategies)
 ">第 20.1 节 “ 抓取策略(Fetching strategies) ”</a>中解释。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="objectstate-querying"></a>11.4. 查询</h2></div></div><div></div></div><p> 如果不知道所要寻找的对象的持久化标识,那么你需要使用查询。Hibernate支持强大且易于使用的面向对象查询语言(HQL)。 如果希望通过编程的方式创建查询,Hibernate提供了完善的按条件(Query By Criteria, QBC)以及按样例(Query By Example, QBE)进行查询的功能。 你也可以用原生SQL(native SQL)描述查询,Hibernate提供了将结果集(result set)转化为对象的部分支持。 </p><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="objectstate-querying-executing"></a>11.4.1. 执行查询</h3></div></div><div></div></div><p> HQL和原生SQL(native SQL)查询要通过为<tt class="literal">org.hibernate.Query</tt>的实例来表达。 这个接口提供了参数绑定、结果集处理以及运行实际查询的方法。 你总是可以通过当前<tt class="literal">Session</tt>获取一个<tt class="literal">Query</tt>对象: </p><pre class="programlisting">List cats = session.createQuery( "from Cat as cat where cat.birthdate < ?") .setDate(0, date) .list();List mothers = session.createQuery( "select mother from Cat as cat join cat.mother as mother where cat.name = ?") .setString(0, name) .list();List kittens = session.createQuery( "from Cat as cat where cat.mother = ?") .setEntity(0, pk) .list();Cat mother = (Cat) session.createQuery( "select cat.mother from Cat as cat where cat = ?") .setEntity(0, izi) .uniqueResult();</pre><p> 一个查询通常在调用<tt class="literal">list()</tt>时被执行,执行结果会完全装载进内存中的一个集合(collection)。 查询返回的对象处于持久(persistent)状态。如果你知道的查询只会返回一个对象,可使用<tt class="literal">list()</tt>的快捷方式<tt class="literal">uniqueResult()</tt>。 </p><div class="sect3" lang="zh-cn"><div class="titlepage"><div><div><h4 class="title"><a name="objectstate-querying-executing-iterate"></a>11.4.1.1. 迭代式获取结果(Iterating results)</h4></div></div><div></div></div><p> 某些情况下,你可以使用<tt class="literal">iterate()</tt>方法得到更好的性能。 这通常是你预期返回的结果在session,或二级缓存(second-level cache)中已经存在时的情况。 如若不然,<tt class="literal">iterate()</tt>会比<tt class="literal">list()</tt>慢,而且可能简单查询也需要进行多次数据库访问: <tt class="literal">iterate()</tt>会首先使用<span class="emphasis"><em>1</em></span>条语句得到所有对象的持久化标识(identifiers),再根据持久化标识执行<span class="emphasis"><em>n</em></span>条附加的select语句实例化实际的对象。 </p><pre class="programlisting">// fetch idsIterator iter = sess.createQuery("from eg.Qux q order by q.likeliness").iterate();while ( iter.hasNext() ) { Qux qux = (Qux) iter.next(); // fetch the object // something we couldnt express in the query if ( qux.calculateComplicatedAlgorithm() ) { // delete the current instance iter.remove(); // dont need to process the rest break; }}</pre></div><div class="sect3" lang="zh-cn"><div class="titlepage"><div><div><h4 class="title"><a name="objectstate-querying-executing-tuples"></a>11.4.1.2. 返回元组(tuples)的查询</h4></div></div><div></div></div><p> (译注:元组(tuples)指一条结果行包含多个对象) Hibernate查询有时返回元组(tuples),每个元组(tuples)以数组的形式返回: </p><pre class="programlisting">Iterator kittensAndMothers = sess.createQuery( "select kitten, mother from Cat kitten join kitten.mother mother") .list() .iterator();while ( kittensAndMothers.hasNext() ) { Object[] tuple = (Object[]) kittensAndMothers.next(); Cat kitten = tuple[0]; Cat mother = tuple[1]; ....}</pre></div><div class="sect3" lang="zh-cn"><div class="titlepage"><div><div><h4 class="title"><a name="objectstate-querying-executing-scalar"></a>11.4.1.3. 标量(Scalar)结果</h4></div></div><div></div></div><p> 查询可在<tt class="literal">select</tt>从句中指定类的属性,甚至可以调用SQL统计(aggregate)函数。 属性或统计结果被认定为"标量(Scalar)"的结果(而不是持久(persistent state)的实体)。 </p><pre class="programlisting">Iterator results = sess.createQuery( "select cat.color, min(cat.birthdate), count(cat) from Cat cat " + "group by cat.color") .list() .iterator();while ( results.hasNext() ) { Object[] row = results.next(); Color type = (Color) row[0]; Date oldest = (Date) row[1]; Integer count = (Integer) row[2]; .....}</pre></div><div class="sect3" lang="zh-cn"><div class="titlepage"><div><div><h4 class="title"><a name="objectstate-querying-executing-parameters"></a>11.4.1.4. 绑定参数</h4></div></div><div></div></div><p> 接口<tt class="literal">Query</tt>提供了对命名参数(named parameters)、JDBC风格的<tt class="literal">问号(?)</tt>参数进行绑定的方法。 <span class="emphasis"><em>不同于JDBC,Hibernate对参数从0开始计数。</em></span> 命名参数(named parameters)在查询字符串中是形如<tt class="literal">:name</tt>的标识符。 命名参数(named parameters)的优点是: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 命名参数(named parameters)与其在查询串中出现的顺序无关 </p></li><li><p> 它们可在同一查询串中多次出现 </p></li><li><p> 它们本身是自我说明的 </p></li></ul></div><pre class="programlisting">//named parameter (preferred)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -