﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-细心!用心!耐心!-文章分类-JPA</title><link>http://www.blogjava.net/jesson2005/category/51978.html</link><description>吾非文人，乃市井一俗人也，读百卷书，跨江河千里，故申城一游； 
一两滴辛酸，三四年学业，五六点粗墨，七八笔买卖，九十道人情。</description><language>zh-cn</language><lastBuildDate>Fri, 15 Jun 2012 15:38:15 GMT</lastBuildDate><pubDate>Fri, 15 Jun 2012 15:38:15 GMT</pubDate><ttl>60</ttl><item><title>JPA本地查询(Native Query)(三)</title><link>http://www.blogjava.net/jesson2005/articles/380885.html</link><dc:creator>张金鹏</dc:creator><author>张金鹏</author><pubDate>Fri, 15 Jun 2012 13:39:00 GMT</pubDate><guid>http://www.blogjava.net/jesson2005/articles/380885.html</guid><wfw:comment>http://www.blogjava.net/jesson2005/comments/380885.html</wfw:comment><comments>http://www.blogjava.net/jesson2005/articles/380885.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesson2005/comments/commentRss/380885.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesson2005/services/trackbacks/380885.html</trackback:ping><description><![CDATA[<div>JPA本地查询(Native Query)(三)</div>
<div>2010-01-20 10:52</div>
<table style="table-layout: fixed; width: 100%">
<tbody>
<tr>
<td>
<div id="blog_text">
<p><span style="font-size: small">最后一种映射类型，就是实体与标量值的组合</span></p>
<p><span style="color: black">&nbsp;</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp; <strong>@SqlResultSetMapping</strong></span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp; (</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>name</strong>=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"ReturnOrderListWithPartEntityPartScalarType"</span><span style="font-size: 10pt; color: black">,</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>entities</strong>=</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>@EntityResult</strong></span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>entityClass</strong>=entity.Order.</span><strong><span style="font-size: 10pt; color: rgb(127,0,85)">class</span></strong><span style="font-size: 10pt; color: black">,</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>fields</strong>=</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>@FieldResult</strong>(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"id"</span><span style="font-size: 10pt; color: black">,column=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"order_id"</span><span style="font-size: 10pt; color: black">),</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <strong>@FieldResult</strong>(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"date"</span><span style="font-size: 10pt; color: black">,column=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"order_creation_date"</span><span style="font-size: 10pt; color: black">),</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <strong>@FieldResult</strong>(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"desc"</span><span style="font-size: 10pt; color: black">,column=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"order_description"</span><span style="font-size: 10pt; color: black">),</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>@FieldResult</strong>(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"sum"</span><span style="font-size: 10pt; color: black">,column=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"order_sum_total"</span><span style="font-size: 10pt; color: black">)</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ),</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>@EntityResult</strong></span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>entityClass</strong>=entity.Customer.</span><strong><span style="font-size: 10pt; color: rgb(127,0,85)">class</span></strong><span style="font-size: 10pt; color: black">,</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>discriminatorColumn</strong>=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"customer_type"</span><span style="font-size: 10pt; color: black">,</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>fields</strong>=</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>@FieldResult</strong>(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"id"</span><span style="font-size: 10pt; color: black">,column=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"customer_id"</span><span style="font-size: 10pt; color: black">),</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>@FieldResult</strong>(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"ctype"</span><span style="font-size: 10pt; color: black">,column=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"customer_type"</span><span style="font-size: 10pt; color: black">)</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>columns</strong>=</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>@ColumnResult</strong>(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"customer_name"</span><span style="font-size: 10pt; color: black">)</span></p>
<p align="left"><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-size: 10pt; color: black">&nbsp;&nbsp;&nbsp; )</span></p>
<p><span style="color: black">&nbsp;</span></p>
<p><span style="font-size: small">我们将结果集中与订单有关的保存进<span style="color: black">Order Entity</span>，把与<span style="color: black">Customer</span>有关的，将<span style="color: black">id</span>和<span style="color: black">customer type</span>&nbsp;保存进<span style="color: black">Customer Entity</span>，把<span style="color: black">customer name</span>保存进标量。 </span></p>
<p><span style="color: black">&nbsp;</span></p>
<p><span style="font-size: small">经过运行测试程序，得到</span></p>
<p><span style="color: black">&nbsp;</span></p>
<p align="left"><span style="font-size: 10pt; color: blue">*****ReturnOrderListWithPartEntityPartScalarType*****</span></p>
<p align="left"><span style="font-size: 10pt; color: blue">entity.Order@48edb5&nbsp;entity.GoldenCustomer@1ee2c2c&nbsp;&nbsp; John Smith </span></p>
<p align="left"><span style="font-size: 10pt; color: blue">entity.Order@1402d5a entity.GoldenCustomer@1ee2c2c&nbsp;&nbsp; John Smith </span></p>
<p><span style="font-size: 10pt; color: blue">entity.Order@1e13e07 entity.GoldenCustomer@1ee2c2c&nbsp;&nbsp; John Smith</span></p>
<p><span style="color: black">&nbsp;</span></p>
<p>综上所述，我们可以采取多种resultset映射机制来保存用本地查询得到的结果集，具体采取哪种要看具体的情况，要继续了解这方面的知识。</p></div></td></tr></tbody></table><br /><img src ="http://www.blogjava.net/jesson2005/aggbug/380885.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesson2005/" target="_blank">张金鹏</a> 2012-06-15 21:39 <a href="http://www.blogjava.net/jesson2005/articles/380885.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JPA本地查询(Native Query)(一)</title><link>http://www.blogjava.net/jesson2005/articles/380883.html</link><dc:creator>张金鹏</dc:creator><author>张金鹏</author><pubDate>Fri, 15 Jun 2012 13:38:00 GMT</pubDate><guid>http://www.blogjava.net/jesson2005/articles/380883.html</guid><wfw:comment>http://www.blogjava.net/jesson2005/comments/380883.html</wfw:comment><comments>http://www.blogjava.net/jesson2005/articles/380883.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesson2005/comments/commentRss/380883.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesson2005/services/trackbacks/380883.html</trackback:ping><description><![CDATA[<div>JPA本地查询(Native Query)(一)</div>
<div>2010-01-20 10:49</div>
<table style="table-layout: fixed; width: 100%">
<tbody>
<tr>
<td>
<div id="blog_text">
<p><span style="font-size: small"><span style="color: rgb(0,0,0)">JPA</span>支持本地查询，所谓本地查询，就是使用原生的<span style="color: rgb(0,0,0)">sql</span>语句（根据数据库的不同，在<span style="color: rgb(0,0,0)">sql</span>的语法或结构方面可能有所区别）进行查询数据库的操作。</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small">本地查询主要使用<span style="color: rgb(0,0,0)">EntityManager</span>接口里的方法：</span></p>
<p><span style="font-size: small"><span style="color: rgb(128,128,128)">public interface EntityManager {<br />public void persist(Object entity);<br />public &lt;T&gt; T find(Class &lt;T&gt; entityClass, Object primaryKey);<br />public &lt;T&gt; T getReference(Class &lt;T&gt; entityClass, Object primaryKey);<br />public &lt;T&gt; T merge(T entity);<br />public void remove(Object entity);<br />public void lock(Object entity, LockModeType lockMode);<br /><br />public void refresh(Object entity);<br />public boolean contains(Object entity);<br />public void clear( );<br /><br />public void joinTransaction( );<br />public void flush( );<br />public FlushModeType getFlushMode( );<br />public void setFlushMode(FlushModeType type);<br /><br />public Query createQuery(String queryString);<br /></span><em><span style="color: rgb(0,0,255)">public Query createNamedQuery(String name);</span></em></span><span style="color: rgb(128,128,128)"><br /><span style="font-size: small">&nbsp;&nbsp; </span></span><em><span style="color: rgb(255,0,0)"><span style="font-size: small">public Query createNativeQuery(String sqlString);<br />public Query createNativeQuery(String sqlString, String resultSetMapping);<br />public Query createNativeQuery(String sqlString, Class resultClass);</span></span></em><span style="color: rgb(128,128,128)"><br /><br /><span style="font-size: small">&nbsp;&nbsp; public Object getDelegate( );<br /><br />public void close( );<br />public boolean isOpen( );<br />}</span></span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small">即<span style="color: rgb(0,0,0)"> createNativeQuery</span>方法的三种形式，但用这个方法的缺点是，要将查询的<span style="color: rgb(0,0,0)">sql</span>语句及返回结果集类型传递进去。还有一种方法是使用<span style="color: rgb(0,0,0)">createNamedQuery</span>，这样就可以避免在这里直接写入<span style="color: rgb(0,0,0)">sql</span>语句以及返回的结果集类型等参数，而可以在相关的<span style="color: rgb(0,0,0)">Entity</span>类里对这些信息进行配置。</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small"><span style="color: rgb(153,153,153)">//</span>这里只是传递进去一个<span style="color: rgb(153,153,153)">string</span>值</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">Query q = </span><span style="font-size: 10pt; color: rgb(0,0,192)">em</span><span style="font-size: 10pt; color: rgb(0,0,0)">.createNamedQuery(</span><span style="font-size: 10pt; color: rgb(42,0,255)">"ReturnOrderListWithFullScalarType"</span><span style="font-size: 10pt; color: rgb(0,0,0)">);</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(153,153,153)">//</span>这里是设定在<span style="font-size: 10pt; color: rgb(153,153,153)">sql</span>中所需的参数</p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">q.setParameter(1, customer.getId());</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(153,153,153)">//</span>得到结果集</p>
<p><span style="font-size: 10pt; color: rgb(0,0,0)">List orderList = q.getResultList();</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small">这个查询主要是根据用户的<span style="color: rgb(0,0,0)">id </span>来获取他名下的所有订单。所以，在实体类<span style="color: rgb(0,0,0)"> Order</span>中，加入相关的<span style="color: rgb(0,0,0)">native query annotation.</span></span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p align="left"><strong><span style="font-size: 10pt; color: rgb(0,0,0)">@NamedNativeQueries</span></strong></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">(</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; {</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>@NamedNativeQuery</strong>(</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>name</strong>=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"ReturnOrderListWithFullScalarType"</span><span style="font-size: 10pt; color: rgb(0,0,0)">,</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>query</strong>=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"select o.id as order_id,o.create_date as order_creation_date,o.description as order_description,o.sum_price as order_sum_total,</span></p>
<p style="margin: 0cm 0cm 0pt 63pt" align="left"><span style="font-size: 10pt; color: rgb(42,0,255)">c.name as customer_name,c.ctype as customer_type,c.id as customer_id from orders o join customer c on o.cust_id=c.id where o.cust_id=?1"</span><span style="font-size: 10pt; color: rgb(0,0,0)">,</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>resultSetMapping</strong>=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"ReturnOrderListWithFullScalarType"</span><span style="font-size: 10pt; color: rgb(0,0,0)">),</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span>。。。。。。。。。。。。。可能还有更多的本地查询设置</p>
<p style="text-indent: 21pt" align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">}</span></p>
<p><span style="font-size: 10pt; color: rgb(0,0,0)">)</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small"><span style="color: rgb(0,0,0)">@NamedNativeQueries </span>如果在一个实体类中有多个<span style="color: rgb(0,0,0)">NamedNativeQuery</span>的话，必须使用该批注，并且将单个的<span style="color: rgb(0,0,0)">NamedNativeQuery</span>都作为<span style="color: rgb(0,0,0)">NamedNativeQueries</span>数组中的一个元素。</span></p>
<p><span style="font-size: small"><span style="color: rgb(0,0,0)">@NamedNativeQuery</span>，在这里设置关于该本地查询的信息。<span style="color: rgb(0,0,255)">name</span>表示传递进<span style="color: rgb(0,0,0)">EntityManager.createNamedQuery(&#8220;</span><span style="color: rgb(0,0,255)">name</span><span style="color: rgb(0,0,0)">&#8221;)</span>的参数，<span style="color: rgb(0,0,255)">query</span>表示实施本地查询的<span style="color: rgb(0,0,0)">sql</span>语句，<span style="color: rgb(0,0,255)">resultSetMapping</span>表示返回结果集的映射方式。它的意思就是结果集将以哪种形式来保存。</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small">接着，就要设置这个结果集的映射方式了。</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p align="left"><strong><span style="font-size: 10pt; color: rgb(0,0,0)">@SqlResultSetMappings</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">(</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">{</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; <strong>@SqlResultSetMapping</strong></span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; (</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>name</strong>=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"ReturnOrderListWithFullScalarType"</span><span style="font-size: 10pt; color: rgb(0,0,0)">,</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>entities</strong>={},</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>columns</strong>=</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@ColumnResult</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"order_id"</span><span style="font-size: 10pt; color: rgb(0,0,0)">),</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@ColumnResult</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"order_creation_date"</span><span style="font-size: 10pt; color: rgb(0,0,0)">),</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@ColumnResult</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"order_description"</span><span style="font-size: 10pt; color: rgb(0,0,0)">),</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@ColumnResult</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"order_sum_total"</span><span style="font-size: 10pt; color: rgb(0,0,0)">),</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@ColumnResult</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"customer_id"</span><span style="font-size: 10pt; color: rgb(0,0,0)">),</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@ColumnResult</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"customer_name"</span><span style="font-size: 10pt; color: rgb(0,0,0)">)</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; ),</span></p>
<p><span style="color: rgb(0,0,0)"><span style="font-size: small">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>。。。。。。。。。。。。。可能还有更多的结果集映射设置</p>
<p><span style="font-size: 10pt; color: rgb(0,0,0)">})</span></p>
<p><span style="font-size: small">针对每一个本地查询的返回值，都有一个结果集和它映射。它可以返回</span></p>
<p><span style="font-size: small"><span style="color: rgb(0,0,0)">1. </span>实体（包括不同类型的实体，即多个实体）<span style="color: rgb(0,0,0)"> Entity</span></span></p>
<p><span style="font-size: small"><span style="color: rgb(0,0,0)">2. </span>标量值<span style="color: rgb(0,0,0)"> Scalar</span></span></p>
<p><span style="font-size: small"><span style="color: rgb(0,0,0)">3. </span>实体与标量值的组合<span style="color: rgb(0,0,0)"> Entity+Scalar</span></span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small">默认情况下，<span style="color: rgb(0,0,0)">JPA</span>假设原生<span style="color: rgb(0,0,0)">sql</span>查询中<span style="color: rgb(0,0,0)">select</span>语句将会：</span></p>
<p><span style="color: rgb(0,0,0)"><span style="font-size: small">1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: small">返回一个实体类型</span></p>
<p><span style="color: rgb(0,0,0)"><span style="font-size: small">2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: small">包含与返回的实体的所有字段或属性相对应的所有列，即列名和实体属性<span style="color: rgb(0,0,0)">/</span>字段名一样</span></p>
<p><span style="color: rgb(0,0,0)"><span style="font-size: small">3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: small">查询中没有用列名别名，<span style="color: rgb(0,0,0)">column alias</span>，即没有用<span style="color: rgb(0,0,0)"> AS </span>指定别名</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small"><span style="color: rgb(0,0,0)">@SqlResultSetMappings</span>，如果在一个实体类中有多个<span style="color: rgb(0,0,0)">@NamedNativeQuery</span>的话，必然就有多个结果集映射<span style="color: rgb(0,0,0)">@SqlResultSetMapping</span>。在这种情况下，必须使用该批注，并且将单个的<span style="color: rgb(0,0,0)">SqlResultSetMapping</span>都作为<span style="color: rgb(0,0,0)">SqlResultSetMappings</span>数组中的一个元素。</span></p>
<p><span style="font-size: small"><span style="color: rgb(0,0,0)">@SqlResultSetMapping</span>，关于结果集映射的详细信息。</span></p>
<p style="margin: 0cm 0cm 0pt 17.95pt"><span style="font-size: small"><span style="color: rgb(0,0,255)">name</span> 表示该结果集映射的名字，与<span style="color: rgb(0,0,0)">@NamedNativeQuery</span>中的</span><span style="font-size: 10pt; color: rgb(0,0,0)">resultSetMapping=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"ReturnOrderListWithFullScalarType"</span><span style="font-size: small">的值相对应。</span></p>
<p style="margin: 0cm 0cm 0pt 17.95pt"><span style="font-size: small"><span style="color: rgb(0,0,255)">entities</span>表示查询结果集会被映射进实体，如果有就要将所有返回的实体一一列出（这里我们将结果集全部映射进标量，所以<span style="color: rgb(0,0,0)">entities</span>属性是个空数组）。</span></p>
<p style="margin: 0cm 0cm 0pt 17.95pt"><span style="font-size: small"><span style="color: rgb(0,0,255)">columns</span>表示将被映射进标量的结果集中的各个列。</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small">这里要说一下标量（<span>Scalar</span>）这个概念。在物理学上，标量与矢量（<span>Vector</span>）是相互对应的，矢量是既有方向又有大小的量，而标量是只有大小的量。在此处，<span>Scalar</span>的含义与物理学上的定义差不多，<span>Scalar</span>可以认为是一个没有属性<span>/</span>方法的单纯的常量<span>(</span>可以想象为<span>java</span>数据类型的<span>primitive type)</span>，而与它相对的则是有方法<span>/</span>属性的对象<span>(object type)</span>。那么采用这种映射机制，我们从数据库取来的每一条记录的每一个字段，仅仅是被单纯的作为一个常量，保存在每一个<span>columnResult</span>中。</span></p>
<p>&nbsp;</p>
<p><span style="font-size: small"><span>@</span> <span style="color: rgb(0,0,0)">ColumnResult</span>，就是指在<span style="color: rgb(0,0,0)">sql</span>语句中，将哪些查询的列保存进来。每一个<span style="color: rgb(0,0,0)">@ColumnResult</span>对应一个列，</span><span style="font-size: 10pt; color: rgb(0,0,0)">name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"order_id"</span><span style="font-size: small"> ，注意，如果在<span style="color: rgb(0,0,0)">select</span>的时候，用<span style="color: rgb(0,0,0)">AS </span>制定了列的别名，&#8220;<span style="color: rgb(0,0,0)">order_id</span>&#8221; 则表示的是别名。</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small">这种映射方式比较简单，我们可以推测，得到的结果集<span style="color: rgb(0,0,0)">List</span>中，数据会是这样：</span></p>
<p><span style="font-size: small"><span style="color: rgb(0,0,0)">[&nbsp;{&#8220;</span>列<span style="color: rgb(0,0,0)">1&#8221;</span><span style="color: rgb(0,0,0)">, &#8220;</span>列<span style="color: rgb(0,0,0)">2&#8221;</span><span style="color: rgb(0,0,0)">, &#8220;</span>列<span style="color: rgb(0,0,0)">3&#8221;</span><span style="color: rgb(0,0,0)">,&nbsp;&#8230;}, &nbsp;{&#8220;</span>列<span style="color: rgb(0,0,0)">1&#8221;</span><span style="color: rgb(0,0,0)">, &#8220;</span>列<span style="color: rgb(0,0,0)">2&#8221;</span><span style="color: rgb(0,0,0)">, &#8220;</span>列<span style="color: rgb(0,0,0)">3&#8221;</span><span style="color: rgb(0,0,0)">,&nbsp;&#8230;}, &#8230;&#8230;&nbsp;]</span></span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small">经过运行测试程序，得到了我们的推论</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,255)">*****ReturnOrderListWithFullScalarType*****</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,255)">52&nbsp;2009-05-27 00:00:00.0&nbsp;&nbsp;&nbsp; This is an order creation example. 36817.0&nbsp;&nbsp;&nbsp; 39&nbsp;John Smith </span></p>
<p><span style="font-size: 10pt; color: rgb(0,0,255)">55&nbsp;2009-05-27 00:00:00.0&nbsp;&nbsp;&nbsp; This is an order creation example. 3347.0 39&nbsp;John Smith</span></p>
<p><span style="font-size: small"><span style="color: rgb(0,0,255)">&#8230;&#8230;</span></span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p>将结果集全部映射进标量，是比较简单的一种做法，在SqlResultSetMapping</p></div></td></tr></tbody></table><img src ="http://www.blogjava.net/jesson2005/aggbug/380883.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesson2005/" target="_blank">张金鹏</a> 2012-06-15 21:38 <a href="http://www.blogjava.net/jesson2005/articles/380883.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JPA本地查询(Native Query)(二)</title><link>http://www.blogjava.net/jesson2005/articles/380884.html</link><dc:creator>张金鹏</dc:creator><author>张金鹏</author><pubDate>Fri, 15 Jun 2012 13:38:00 GMT</pubDate><guid>http://www.blogjava.net/jesson2005/articles/380884.html</guid><wfw:comment>http://www.blogjava.net/jesson2005/comments/380884.html</wfw:comment><comments>http://www.blogjava.net/jesson2005/articles/380884.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesson2005/comments/commentRss/380884.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesson2005/services/trackbacks/380884.html</trackback:ping><description><![CDATA[<div>JPA本地查询(Native Query)(二)</div>
<div>2010-01-20 10:49</div>
<table style="table-layout: fixed; width: 100%">
<tbody>
<tr>
<td>
<div id="blog_text">
<p><span style="font-size: small"><span style="color: rgb(0,0,0)">OK</span>，现在对同一个查询，再把结果集全部映射进实体对象。</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small">首先</span></p>
<p align="left"><strong><span style="font-size: 10pt; color: rgb(0,0,0)">@NamedNativeQueries</span></strong></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">(</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; {</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>@NamedNativeQuery</strong>(</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>name</strong>=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"</span><span style="font-size: 10pt; color: rgb(255,0,0)">ReturnOrderListWithFullEntityType</span><span style="font-size: 10pt; color: rgb(42,0,255)">"</span><span style="font-size: 10pt; color: rgb(0,0,0)">,</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>query</strong>=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"select </span><span style="font-size: 10pt; color: rgb(255,0,0)">o.id</span><span style="font-size: 10pt; color: rgb(42,0,255)"> as order_id,o.create_date as order_creation_date,o.description as order_description,o.sum_price as order_sum_total,</span></p>
<p style="margin: 0cm 0cm 0pt 63pt" align="left"><span style="font-size: 10pt; color: rgb(42,0,255)">c.name as customer_name,</span><span style="font-size: 10pt; color: rgb(255,0,0)">c.ctype</span><span style="font-size: 10pt; color: rgb(42,0,255)"> as customer_type,</span><span style="font-size: 10pt; color: rgb(255,0,0)">c.id</span><span style="font-size: 10pt; color: rgb(42,0,255)"> as customer_id from orders o join customer c on o.cust_id=c.id where o.cust_id=?1"</span><span style="font-size: 10pt; color: rgb(0,0,0)">,</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>resultSetMapping</strong>=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"</span><span style="font-size: 10pt; color: rgb(255,0,0)">ReturnOrderListWithFullEntityType</span><span style="font-size: 10pt; color: rgb(42,0,255)">"</span><span style="font-size: 10pt; color: rgb(0,0,0)">),</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span>。。。。。。。。。。。。。可能还有更多的本地查询设置</p>
<p style="text-indent: 21pt" align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">}</span></p>
<p><span style="font-size: 10pt; color: rgb(0,0,0)">)</span></p>
<p><span style="font-size: small">改变本地查询的<span style="color: rgb(0,0,0)">resultSetMapping</span></span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@SqlResultSetMapping</span></strong></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; (</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>name</strong>=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"ReturnOrderListWithFullEntityType"</span><span style="font-size: 10pt; color: rgb(0,0,0)">,</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>entities</strong>=</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@EntityResult</span></strong></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>entityClass</strong>=entity.Order.</span><strong><span style="font-size: 10pt; color: rgb(127,0,85)">class</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">,</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>fields</strong>=</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@FieldResult</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"id"</span><span style="font-size: 10pt; color: rgb(0,0,0)">,column=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"order_id"</span><span style="font-size: 10pt; color: rgb(0,0,0)">),</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@FieldResult</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"date"</span><span style="font-size: 10pt; color: rgb(0,0,0)">,column=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"order_creation_date"</span><span style="font-size: 10pt; color: rgb(0,0,0)">),</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@FieldResult</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"desc"</span><span style="font-size: 10pt; color: rgb(0,0,0)">,column=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"order_description"</span><span style="font-size: 10pt; color: rgb(0,0,0)">),</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@FieldResult</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"sum"</span><span style="font-size: 10pt; color: rgb(0,0,0)">,column=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"order_sum_total"</span><span style="font-size: 10pt; color: rgb(0,0,0)">)</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ),</span></p>
<p align="left">&nbsp;</p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@EntityResult</span></strong></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>entityClass</strong>=entity.Customer.</span><strong><span style="font-size: 10pt; color: rgb(127,0,85)">class</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">,</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>discriminatorColumn</strong>=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"customer_type"</span><span style="font-size: 10pt; color: rgb(0,0,0)">,</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>fields</strong>=</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@FieldResult</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"id"</span><span style="font-size: 10pt; color: rgb(0,0,0)">,column=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"customer_id"</span><span style="font-size: 10pt; color: rgb(0,0,0)">),</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt">@FieldResult</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">(name=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"name"</span><span style="font-size: 10pt; color: rgb(0,0,0)">,column=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"customer_name"</span><span style="font-size: 10pt; color: rgb(0,0,0)">)</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>columns</strong>={}</span></p>
<p><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; )</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small"><span style="color: rgb(0,0,255)">entities</span>属性是一个包含与返回结果集相映射的所有实体的一个数组。这条查询得到了订单和用户的信息，所以，与结果集映射的实体，就应该是<span style="color: rgb(0,0,0)">Order</span>和<span style="color: rgb(0,0,0)">Customer</span>。</span></p>
<p><span style="font-size: small">每一个映射实体用<span style="color: rgb(0,0,255)">@EntityResult</span>表示，<span style="color: rgb(0,0,255)">entityClass</span>表示实体类，<span style="color: rgb(0,0,255)">fields</span>表示该实体类中的属性，与查询结果中的哪些个列相映射。而每一个&#8220;属性<span style="color: rgb(0,0,0)">&lt;-&gt;</span>列&#8221;的映射关系，又保存在<span style="color: rgb(0,0,255)">@FieldResult</span>里面。<span style="color: rgb(0,0,255)">name</span>是实体属性，<span style="color: rgb(0,0,255)">column</span>是查询列（或列别名）</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small">要注意的是，如果要将结果集映射到实体对象，则</span></p>
<p><span style="font-size: small"><span style="color: rgb(0,0,0)">1</span>．<span style="color: rgb(0,0,0)">Select </span>语句中必须包含实体所映射的表中的<span style="color: rgb(0,0,0)">PK</span>，也就是 </span><span style="font-size: 10pt; color: rgb(42,0,255)">select </span><span style="font-size: 10pt; color: rgb(255,0,0)">o.id</span><span style="font-size: 10pt; color: rgb(42,0,255)"> as order_id</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small"><span style="color: rgb(0,0,0)">2. </span>反过来，&#8220;属性<span style="color: rgb(0,0,0)">&lt;-&gt;</span>列&#8221;的映射，也必须将表的<span style="color: rgb(0,0,0)">PK</span>映射到实体类的用<span style="color: rgb(0,0,0)">@Id annotation</span>批注的字段或属性上。</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small">否则，<span style="color: rgb(0,0,0)">JPA</span>就会抛出一个<span style="color: rgb(0,0,0)">exception</span></span></p>
<p align="left"><span style="text-decoration: underline"><span style="font-size: 10pt; color: rgb(0,0,128)">oracle.toplink.essentials.exceptions.QueryException</span></span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">Exception Description: The primary key read from the row [DatabaseRecord(</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; orders.ID =&gt; null</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; orders.CREATE_DATE =&gt; 2009-05-27 00:00:00.0</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; orders.SUM_PRICE =&gt; 36817.0</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; orders.DESCRIPTION =&gt; This is an order creation example.</span></p>
<p><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; orders.cust_id =&gt; null)] </span><span style="font-size: 10pt; color: rgb(255,0,0)">during the execution of the query was detected to be null.&nbsp;Primary keys must not contain null.</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small">再看一下关于<span style="color: rgb(0,0,0)">Customer</span>实体的映射，与<span style="color: rgb(0,0,0)">Order</span>不一样的地方，是</span><strong><span style="font-size: 10pt; color: rgb(0,0,0)">discriminatorColumn</span></strong><span style="font-size: 10pt; color: rgb(0,0,0)">=</span><span style="font-size: 10pt; color: rgb(42,0,255)">"customer_type" </span><span style="font-size: 10pt; color: rgb(0,0,0)">(</span>可能为列别名<span style="font-size: 10pt; color: rgb(0,0,0)">)</span></p>
<p><span style="font-size: small">加上这个属性的原因是，<span style="color: rgb(0,0,0)">Customer</span>类是一个父类，以供其他子类继承，而<span style="color: rgb(0,0,0)">J PA</span>的内在多态性机制将会获取到<span style="color: rgb(0,0,0)">Customer</span>的实际类型。根据<span style="color: rgb(0,0,0)">J PA @Inheritance</span>批注，得知，父类实体的表中必须有一个字段（默认为<span style="color: rgb(0,0,0)">DTYPE</span>）来表示各个子类的类型。所以当要将查询结果集保存为实体的时候，它必须要知道你所保存的这个<span style="color: rgb(0,0,0)">Customer</span>实体到底是哪种类型。</span></p>
<p><span style="font-size: small">所以，你还必须在<span style="color: rgb(0,0,0)">select</span>子句中取得这个<span style="color: rgb(0,0,0)">Discrimator Type</span>的字段。</span></p>
<p><span style="font-size: small">否则又会抛出异常：<span style="color: rgb(0,0,0)">&nbsp;</span></span></p>
<p align="left"><span style="text-decoration: underline"><span style="font-size: 10pt; color: rgb(0,0,128)">oracle.toplink.essentials.exceptions.QueryException</span></span></p>
<p><span style="font-size: 10pt; color: rgb(0,0,0)">Exception Description: </span><span style="font-size: 10pt; color: rgb(255,0,0)">Custom SQL failed to provide descriminator column : , as defined in SQLResultSetMapping : ReturnOrderListWithFullEntityType.</span></p>
<p><span style="font-size: small">或者：</span></p>
<p align="left"><span style="text-decoration: underline"><span style="font-size: 10pt; color: rgb(0,0,128)">oracle.toplink.essentials.exceptions.QueryException</span></span></p>
<p><span style="font-size: 10pt; color: rgb(0,0,0)">Exception Description: </span><span style="font-size: 10pt; color: rgb(255,0,0)">Custom SQL failed to provide descriminator column : customer_type, as defined in SQLResultSetMapping : ReturnOrderListWithPartEntityPartScalarType.</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small">通过这种映射方式，我们可以推测，得到的结果集<span style="color: rgb(0,0,0)">List</span>中，数据会是这样：</span></p>
<p><span style="font-size: small"><span style="color: rgb(0,0,0)">[&nbsp;{&#8220;Order</span>对象<span style="color: rgb(0,0,0)">1&#8221;</span><span style="color: rgb(0,0,0)">, &#8220;Customer</span>对象<span style="color: rgb(0,0,0)">1&#8221;</span><span style="color: rgb(0,0,0)">},&nbsp;{&#8220;Order</span>对象<span style="color: rgb(0,0,0)">2&#8221;</span><span style="color: rgb(0,0,0)">, &#8220;Customerr</span>对象<span style="color: rgb(0,0,0)">2&#8221;</span><span style="color: rgb(0,0,0)">}, &#8230;&#8230;&nbsp;]</span></span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p><span style="font-size: small">经过运行测试程序，得到了我们的推论</span></p>
<p><span style="color: rgb(0,0,0)">&nbsp;</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,255)">*****ReturnOrderListWithFullEntityType*****</span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,255)">entity.Order@48edb5&nbsp;entity.GoldenCustomer@1ee2c2c&nbsp;&nbsp; </span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,255)">entity.Order@1402d5a entity.GoldenCustomer@1ee2c2c&nbsp;&nbsp; </span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,255)">entity.Order@1e13e07 entity.GoldenCustomer@1ee2c2c&nbsp;&nbsp; </span></p>
<p align="left"><span style="font-size: 10pt; color: rgb(0,0,255)">entity.Order@9cfec1&nbsp;entity.GoldenCustomer@1ee2c2c&nbsp;&nbsp; </span></p>
<p><span style="font-size: 10pt; color: rgb(0,0,255)">entity.Order@747fa2&nbsp;entity.GoldenCustomer@1ee2c2c</span><span style="font-size: 10pt; color: rgb(0,0,0)">&nbsp;&nbsp; </span></p>
<p><span style="color: rgb(0,0,0)"><span style="font-size: small">&#8230;&#8230;</span></span></p>
<p>看来的确是保存了对象，而且注意第二个对象不是Customer而是GoldenCustomer，这说明，JPA自动将数据映射进了GoldenCustomer实体（尽管我们使用的是Customer实体进行保存&nbsp;&#8220;<strong>entityClass</strong>=entity.Customer.<strong>class&#8221;</strong>）</p></div></td></tr></tbody></table><br /><img src ="http://www.blogjava.net/jesson2005/aggbug/380884.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesson2005/" target="_blank">张金鹏</a> 2012-06-15 21:38 <a href="http://www.blogjava.net/jesson2005/articles/380884.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>createNativeQuery原生－命名查询</title><link>http://www.blogjava.net/jesson2005/articles/380882.html</link><dc:creator>张金鹏</dc:creator><author>张金鹏</author><pubDate>Fri, 15 Jun 2012 13:37:00 GMT</pubDate><guid>http://www.blogjava.net/jesson2005/articles/380882.html</guid><wfw:comment>http://www.blogjava.net/jesson2005/comments/380882.html</wfw:comment><comments>http://www.blogjava.net/jesson2005/articles/380882.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesson2005/comments/commentRss/380882.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesson2005/services/trackbacks/380882.html</trackback:ping><description><![CDATA[<div class="tit">createNativeQuery原生－命名查询</div>
<div class="date">2010-01-20 10:27</div>
<table style="table-layout: fixed; width: 100%">
<tbody>
<tr>
<td>
<div class="cnt" id="blog_text">
<p>9.3.原生查询<br />EJB QL中富有大量的查询语句并且基本上能符合你的绝大多数的查询需求.有时,你想要使用特定厂商提供的数据库上的专有能力.<br />实体管理服务提供了一个方法来建立原生的SQL查询并且映射他们到你的对象上.原生查询能反回实体,栏位值,或者两者的组合.EntityManager接口有三种方法来建立原生查询:一种返回标量值,一种是返回实体类型,最后一种是定义一个复杂的结果集,它能映射到多个实体的混合和标量值.<br />你可以进行JDBC的连接通过javax.sql.DataSource,使用@Resource注入和执行你的SQL语句.要意识到你所做的改变不会被当前的持久化上下文所反映.</p>
<p>9.3.1. 标量原生查询<br />Query createNativeQuery(String sql)<br />这将建立一个原生查询返回一个标量结果.它需要一个参数:你的原生SQL.它执行并且返回结果集同EJB QL相同的形式,返回标量值.</p>
<p>9.3.2.简单的实体原生查询<br />Query createNativeQuery(String sql, Class entityClass) <br />一个简单的原生查询通过一个SQL语句和隐式的映像到一个实体,映射元数据为基础的一个实体.它认为原生查询的结果集中的栏将完全匹配实体的O/R映射.原生SQL查询的映射实体的确定通过entityClass 参数:<br />Query query = manager.createNativeQuery(<br />"SELECT p.phone_PK, p.phone_number, p.type<br />FROM PHONE AS p", Phone.class<br />);<br />实体的所有属性被列出:</p>
<p>9.3.3.复杂的原生查询<br />这个实体管理方法允许你有一个复杂的映射为原生SQL.你可以同时返回多个实体和标量栏.mappingName 参数参考@javax.persistence.SqlResultSetMapping定义.这个批注用来定义一个怎能样查询原生结果的钓子到O/R模型.如果返回的栏位名与批注映射的属性不匹配,你可以提代一个字段到栏位的映射为他们,使用@javax.persistence.FieldResult :<br />package javax.persistence;</p>
<p>public @interface SqlResultSetMapping {<br />String name( );<br />EntityResult[] entities( ) default {};<br />ColumnResult[] columns( ) default {};<br />}</p>
<p>public @interface EntityResult {<br />Class entityClass( );<br />FieldResult[] fields( ) default {};<br />String discriminatorColumn( ) default "";<br />}</p>
<p>public @interface FieldResult {<br />String name( );<br />String column( );<br />}</p>
<p>public @interface ColumnResult {<br />String name( );<br />}<br />让我们做一系列的例子表示这会如何工作.</p>
<p>9.3.3.1. 使用多个实体的原生查询<br />@Entity<br />@SqlResultSetMapping(name="customerAndCreditCardMapping",<br /><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#101;&#110;&#116;&#105;&#116;&#105;&#101;&#115;&#61;&#37;&#55;&#66;&#64;&#69;&#110;&#116;&#105;&#116;&#121;&#82;&#101;&#115;&#117;&#108;&#116;&#37;&#50;&#56;&#101;&#110;&#116;&#105;&#116;&#121;&#67;&#108;&#97;&#115;&#115;&#61;&#67;&#117;&#115;&#116;&#111;&#109;&#101;&#114;&#46;&#99;&#108;&#97;&#115;&#115;">entities={@EntityResult(entityClass=Customer.class</a>),<br />@EntityResult(entityClass=CreditCard.class,<br /><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#102;&#105;&#101;&#108;&#100;&#115;&#61;&#37;&#55;&#66;&#64;&#70;&#105;&#101;&#108;&#100;&#82;&#101;&#115;&#117;&#108;&#116;&#37;&#50;&#56;&#110;&#97;&#109;&#101;&#61;&#37;&#50;&#50;&#105;&#100;">fields={@FieldResult(name="id</a>",<br />column="CC_ID"),<br />@FieldResult(name="number",<br />column="number")}<br />)})<br />public class Customer {...}</p>
<p>// execution code<br />{<br />Query query = manager.createNativeQuery(<br />"SELECT c.id, c.firstName, cc.id As CC_ID, <br />cc.number" +<br />"FROM CUST_TABLE c, CREDIT_CARD_TABLE cc" +<br />"WHERE c.credit_card_id = cc.id",<br />"customerAndCreditCardMapping");<br />}<br />因为结果集返回多个实体类型,我们必需使用一个@SqlResultSetMapping.这个批注可以被放在一个实体类或方法上.entities( )属性用来设置@EntityResult批注组成的队列.每一个@EntityResult注释指定将要通过原生SQL查询返回的实体.<br />@javax.persistence.FieldResult注释用来明确查询中与实体属性对应的映射栏位<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#46;&#64;&#70;&#105;&#101;&#108;&#100;&#82;&#101;&#115;&#117;&#108;&#116;">.@FieldResult</a>批注的name()属性标识实体组件的属性, column( ) 属性标识通过原生查询返回的结果集栏位.<br />在这个例子中,我们需要指定@FieldResults为客户.原生查询为实体引用的每一个栏位.因为我们只查询CreditCard 实体的ID和number栏,@FieldResult批注需要被指定.在 CreditCard的@EntityResult批注中,fields()属性定义CreditCard 属性每次查询的映射.因为Customer和CreditCard主键栏有相同的名子,SQL查询需要辨别出他们的不同.cc.id As CC_ID这段SQL代码演示出这种标识.<br />我们也可以使用XML来表达：<br />&lt;entity-mappings&gt;<br />&lt;sql-result-set-mapping name="customerAndCreditCardMapping"&gt;<br />&lt;entity-result entity-class="com.titan.domain.Customer"/&gt;<br />&lt;entity-result entity-class="com.titan.domain.CreditCard"/&gt;<br />&lt;field-result name="id" column="CC_ID"/&gt;<br />&lt;field-result name="number" column="number"/&gt;<br />&lt;/entity-result&gt;<br />&lt;/sql-result-set-mapping&gt;<br />&lt;/entity-mappings&gt;<br />9.3.3.2.混合标量和实体结果<br />在我们的最终例子,显示一个实体和一个标量值的混合.我们写一个原生查询,来返回一个每次巡行由多少预定组成的巡行列表.<br />@SqlResultSetMapping(name="reservationCount",<br /><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#101;&#110;&#116;&#105;&#116;&#105;&#101;&#115;&#61;&#64;&#69;&#110;&#116;&#105;&#116;&#121;&#82;&#101;&#115;&#117;&#108;&#116;&#37;&#50;&#56;&#110;&#97;&#109;&#101;&#61;&#37;&#50;&#50;&#99;&#111;&#109;&#46;&#116;&#105;&#116;&#97;&#110;&#46;&#100;&#111;&#109;&#97;&#105;&#110;&#46;&#67;&#114;&#117;&#105;&#115;&#101;">entities=@EntityResult(name="com.titan.domain.Cruise</a>",<br /><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#102;&#105;&#101;&#108;&#100;&#115;&#61;&#64;&#70;&#105;&#101;&#108;&#100;&#82;&#101;&#115;&#117;&#108;&#116;&#37;&#50;&#56;&#110;&#97;&#109;&#101;&#61;&#37;&#50;&#50;&#105;&#100;">fields=@FieldResult(name="id</a>", column="id")),<br /><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#99;&#111;&#108;&#117;&#109;&#110;&#115;&#61;&#64;&#67;&#111;&#108;&#117;&#109;&#110;&#82;&#101;&#115;&#117;&#108;&#116;&#37;&#50;&#56;&#110;&#97;&#109;&#101;&#61;&#37;&#50;&#50;&#114;&#101;&#115;&#67;&#111;&#117;&#110;&#116;">columns=@ColumnResult(name="resCount</a>"))<br />@Entity<br />public class Cruise {...}</p>
<p>{<br />Query query = manager.createNativeQuery(<br />"SELECT c.id, count(Reservation.id) as resCount</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM Cruise c LEFT JOIN Reservation ON c.id = Reservation.CRUISE_ID<br />GROUP BY c.id",<br />"reservationCount"); <br />}<br />reservationCount映射的定义,原生查询表现对一个巡航实体和一个所有巡航预定的数目的请求<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#46;&#64;&#70;&#105;&#101;&#108;&#100;&#82;&#101;&#115;&#117;&#108;&#116;">.@FieldResult</a>批注标识c.id栏同Cruise实体相关联<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#46;&#64;&#67;&#111;&#108;&#117;&#109;&#110;&#82;&#101;&#115;&#117;&#108;&#116;">.@ColumnResult</a>批注标识resCount栏同一个标量值.<br />等价的XML文件:<br />&lt;entity-mappings&gt;<br />&lt;sql-result-set-mapping name="reservationCount"&gt;<br />&lt;entity-result entity-class="com.titan.domain.Cruise"&gt;<br />&lt;field-result name="id" column="id"/&gt;<br />&lt;/entity-result&gt;<br />&lt;column-result name="resCount"/&gt;<br />&lt;/sql-result-set-mapping&gt;<br />&lt;/entity-mappings&gt;</p>
<p>9.4命名查询<br />JAVA持久化提供了一种机制,所以在建立一个查询时,你可以预先定义EJB QL或原SQL查询,并且引用它们通过名字.你可以先建立查询,然后建立JAVA语言中的String类型的常量:在多种不同的情形中重复使用他们.你预先定义一个查询,当在后面用到的时候,可以很容易的进行调整<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#46;&#64;&#106;&#97;&#118;&#97;&#120;&#46;&#112;&#101;&#114;&#115;&#105;&#115;&#116;&#101;&#110;&#99;&#101;&#46;&#78;&#97;&#109;&#101;&#100;&#81;&#117;&#101;&#114;&#121;">.@javax.persistence.NamedQuery</a> 批注用在预定义EJB QL中:<br />package javax.persistence;<br />public @interface NamedQuery {<br />String name( );<br />String query( );<br />QueryHint[] hints( ) default {};<br />}<br />public @interface QueryHint {<br />String name( );<br />String value( );<br />}<br />public @interface NamedQueries {<br />NamedQuery[] value( );<br />}<br />当你定义一个或多个查询在类或包中,你可以使用@javax.persistence.NamedQueries 批注<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#46;&#64;&#106;&#97;&#118;&#97;&#120;&#46;&#112;&#101;&#114;&#115;&#105;&#115;&#116;&#101;&#110;&#99;&#101;&#46;&#81;&#117;&#101;&#114;&#121;&#72;&#105;&#110;&#116;">.@javax.persistence.QueryHint</a>批注定义厂商提供的暗示.这些暗示工作方式与Query.setHint( )方法类似,它的描述在本单的前面.这是一个例:<br />package com.titan.domain;<br />import javax.persistence.*;<br />@NamedQueries({<br />@NamedQuery <br />(name="getAverageReservation",<br />query=<br />"SELECT AVG( r.amountPaid)<br />FROM Cruise As c, JOIN c.reservations r<br />WHERE c = :cruise"),</p>
<p>&nbsp;&nbsp;&nbsp; @NamedQuery(name="findFullyPaidCruises",<br />query=<br />"FROM Cruise cr<br />WHERE 0 &lt; ALL (<br />SELECT res.amountPaid from cr.reservations res<br />)")<br />})<br />@Entity<br />public class Cruise {...}<br />在这个例子中定义了两个EJB QL查询在Cruise实体组件类.你可以引用这些定义在EntityManager.createNamedQuery( )方法中:<br />Query query = em.createNamedQuery("findFullyPaidCruises");<br />Query.setParameter("cruise", cruise);<br />等价于@NamedQuery的XML文件:<br />&lt;entity-mappings&gt;<br />&lt;named-query <br />name="getAverageReservation"&gt;<br />&lt;query&gt;<br />SELECT AVG( r.amountPaid)<br />FROM Cruise As c JOIN c.reservations r<br />WHERE c = :cruise<br />&lt;/query&gt;<br />&lt;/named-query&gt;<br />&lt;/entity-mappings&gt;</p>
<p>9.4.1.命名原生查询<br />@javax.persistence.NamedNativeQuery 批注用于预处理原生SQL查询:<br />package javax.persistence;</p>
<p>public @interface NamedNativeQuery {<br />String name( );<br />String query( );<br />Class resultClass( ) default void.class;<br />String resultSetMapping( ) default "";<br />}</p>
<p>public @interface NamedNativeQueries {<br />NamedNativeQuery[] value( );<br />}<br />resultClass() 属性是为当你有一个原生查询时,只返回一个实体类型.(看这章的前面"Native Queries" 节).resultSetMapping( ) 属性解决一个预定@SqlResultSetMapping.这两个属性是可选的,但是你必需至少定义它们中的一个.这是@NamedNativeQuery批注的一个例子:<br />@NamedNativeQuery(<br />name="findCustAndCCNum",<br />query="SELECT c.id, c.firstName, c.lastName, cc.number AS CC_NUM<br />FROM CUST_TABLE c, CREDIT_CARD_TABLE cc<br />WHERE c.credit_card_id = cc.id",<br />resultSetMapping="customerAndCCNumMapping")<br />@SqlResultSetMapping(name="customerAndCCNumMapping",<br /><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#101;&#110;&#116;&#105;&#116;&#105;&#101;&#115;&#61;&#37;&#55;&#66;&#64;&#69;&#110;&#116;&#105;&#116;&#121;&#82;&#101;&#115;&#117;&#108;&#116;&#37;&#50;&#56;&#101;&#110;&#116;&#105;&#116;&#121;&#67;&#108;&#97;&#115;&#115;&#61;&#67;&#117;&#115;&#116;&#111;&#109;&#101;&#114;&#46;&#99;&#108;&#97;&#115;&#115;">entities={@EntityResult(entityClass=Customer.class</a>)},<br /><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#99;&#111;&#108;&#117;&#109;&#110;&#115;&#61;&#37;&#55;&#66;&#64;&#67;&#111;&#108;&#117;&#109;&#110;&#82;&#101;&#115;&#117;&#108;&#116;&#37;&#50;&#56;&#110;&#97;&#109;&#101;&#61;&#37;&#50;&#50;&#67;&#67;&#95;&#78;&#85;&#77;">columns={@ColumnResult(name="CC_NUM</a>")}<br />)<br />@Entity<br />public class Customer {...}<br />你可以参考EntityManager.createNamedQuery( ) 的定义:<br />Query query = em.createNamedQuery("findCustAndCCNum");<br />等价的XML文件:<br />&lt;entity-mappings&gt;<br />&lt;named-native-query name="findCustAndCCNum"<br />result-set-mapping="customerAndCCNumMapping"/&gt;<br />&lt;query&gt;<br />SELECT c.id, c.firstName, c.lastName,<br />cc.number AS CC_NUM<br />FROM CUST_TABLE c, CREDIT_CARD_TABLE cc<br />WHERE c.credit_card_id = cc.id<br />&lt;/query&gt;<br />&lt;/named-native-query&gt;<br />&lt;/entity-mappings&gt;</p>
<p>Phone实体中加入<br />@NamedNativeQuery(name="NativePhone",<br />query="SELECT p.phone_PK, p.phone_number, p.type FROM PHONE AS p",<br />resultClass=Phone.class)<br />Named Native Query, implicit mapping<br />--------------------------------<br />Executing @NamedNativeQuery(name="NativePhone")<br />Exception in thread "main" javax.persistence.RollbackException: Transaction marked as rollbackOnly<br />at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:50)<br />at com.lyh.ejb3.clients.NativeQueries.main(NativeQueries.java:42)</p>
<p><br />Initialize DB<br />Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.MappingException: Named query not known: NativePhone<br />at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:567)<br />at org.hibernate.ejb.AbstractEntityManagerImpl.createNamedQuery(AbstractEntityManagerImpl.java:90)<br />at com.lyh.ejb3.clients.NativeQueries.nativeSql(NativeQueries.java:54)<br />at com.lyh.ejb3.clients.NativeQueries.main(NativeQueries.java:34)<br />Caused by: org.hibernate.MappingException: Named query not known: NativePhone</p>
<p>Named Native Query, implicit mapping<br />--------------------------------<br />Executing @NamedNativeQuery(name="NativePhone")</p>
<p>at org.hibernate.impl.AbstractSessionImpl.getNamedQuery(AbstractSessionImpl.java:70)<br />at org.hibernate.impl.SessionImpl.getNamedQuery(SessionImpl.java:1260)<br />at org.hibernate.ejb.AbstractEntityManagerImpl.createNamedQuery(AbstractEntityManagerImpl.java:87)<br />... 2 more</p>
<p><br />Customer实体中加入<br />@Table(name="CUST_TABLE")<br />@SqlResultSetMapping(name="customerAndCreditCardMapping",<br /><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#101;&#110;&#116;&#105;&#116;&#105;&#101;&#115;&#61;&#37;&#55;&#66;&#64;&#69;&#110;&#116;&#105;&#116;&#121;&#82;&#101;&#115;&#117;&#108;&#116;&#37;&#50;&#56;&#101;&#110;&#116;&#105;&#116;&#121;&#67;&#108;&#97;&#115;&#115;&#61;&#67;&#117;&#115;&#116;&#111;&#109;&#101;&#114;&#46;&#99;&#108;&#97;&#115;&#115;">entities={@EntityResult(entityClass=Customer.class</a>),<br />@EntityResult(entityClass=CreditCard.class,<br /><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#102;&#105;&#101;&#108;&#100;&#115;&#61;&#37;&#55;&#66;&#64;&#70;&#105;&#101;&#108;&#100;&#82;&#101;&#115;&#117;&#108;&#116;&#37;&#50;&#56;&#110;&#97;&#109;&#101;&#61;&#37;&#50;&#50;&#105;&#100;">fields={@FieldResult(name="id</a>", column="CC_ID"),<br />@FieldResult(name="number", column="number")}<br />)})<br />Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.MappingException: Unknown SqlResultSetMapping [customerAndCreditCardMapping]<br />at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:567)<br />at org.hibernate.ejb.AbstractEntityManagerImpl.createNativeQuery(AbstractEntityManagerImpl.java:128)<br />at com.lyh.ejb3.clients.NativeQueries.nativeWithMultipleEntities(NativeQueries.java:74)<br />at com.lyh.ejb3.clients.NativeQueries.main(NativeQueries.java:36)<br />Caused by: org.hibernate.MappingException: Unknown SqlResultSetMapping [customerAndCreditCardMapping]<br />at org.hibernate.impl.SQLQueryImpl.setResultSetMapping(SQLQueryImpl.java:290)<br />at org.hibernate.ejb.AbstractEntityManagerImpl.createNativeQuery(AbstractEntityManagerImpl.java:124)<br />... 2 more</p>
<p>加入@Table(name="CREDIT_CARD_TABLE") 并在相应属性加入@Column批注<br />ERROR - Table 'titan.credit_card_table' doesn't exist</p>
<p>at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)<br />at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)<br />at org.hibernate.loader.Loader.doList(Loader.java:2147)<br />at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2028)<br />at org.hibernate.loader.Loader.list(Loader.java:2023)<br />at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:289)<br />at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1695)<br />at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:142)<br />at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:150)<br />at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:53)<br />... 2 more<br />强制类型转换<br />Exception in thread "main" java.lang.ClassCastException: java.math.BigInteger<br />at com.lyh.ejb3.clients.NativeQueries.mixedNative(NativeQueries.java:109)<br />at com.lyh.ejb3.clients.NativeQueries.main(NativeQueries.java:38)</p></div></td></tr></tbody></table><br /><img src ="http://www.blogjava.net/jesson2005/aggbug/380882.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesson2005/" target="_blank">张金鹏</a> 2012-06-15 21:37 <a href="http://www.blogjava.net/jesson2005/articles/380882.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JPA EntityManager详解(二)</title><link>http://www.blogjava.net/jesson2005/articles/380881.html</link><dc:creator>张金鹏</dc:creator><author>张金鹏</author><pubDate>Fri, 15 Jun 2012 13:36:00 GMT</pubDate><guid>http://www.blogjava.net/jesson2005/articles/380881.html</guid><wfw:comment>http://www.blogjava.net/jesson2005/comments/380881.html</wfw:comment><comments>http://www.blogjava.net/jesson2005/articles/380881.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesson2005/comments/commentRss/380881.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesson2005/services/trackbacks/380881.html</trackback:ping><description><![CDATA[<div class="tit">JPA EntityManager详解(二)</div>
<table style="table-layout: fixed; width: 100%">
<tbody>
<tr>
<td>
<div class="cnt" id="blog_text">&#9733; 提示 &#9733;<br /><br />目前JBoss 4.2集成了的Tomcat版本为5.5，但Tomcat 6.0以后的版本中才支持使用注释，所以如果将本例中Servlet运行在JBoss 4.2中，并不能获得EntityManagerFactory对象；但在符合J2EE 5.0的服务器中，这样运行是可以的。<br /><br />虽然在目前JBoss 4.2版本中不支持使用注释，但可以通过另一种方式来获得应用托管的EntityManager对象。代码如下所示。<br /><br />1. public class TestServlet extends HttpServlet {&nbsp; <br />2.&nbsp;&nbsp; <br />3.&nbsp;&nbsp;&nbsp;&nbsp; private EntityManagerFactory emf;&nbsp; <br />4.&nbsp;&nbsp; <br />5.&nbsp;&nbsp;&nbsp;&nbsp; public TestServlet() {&nbsp; <br />6.&nbsp;&nbsp; <br />7.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super();&nbsp; <br />8.&nbsp;&nbsp; <br />9.&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />10.&nbsp;&nbsp; <br />11.&nbsp;&nbsp;&nbsp;&nbsp; public void doGet(HttpServletRequest request, HttpServletResponse response)&nbsp; <br />12.&nbsp;&nbsp; <br />13.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws ServletException, IOException {&nbsp; <br />14.&nbsp;&nbsp; <br />15.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doPost(request, response);&nbsp; <br />16.&nbsp;&nbsp; <br />17.&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />18.&nbsp;&nbsp; <br />19.&nbsp;&nbsp;&nbsp;&nbsp; public void doPost(HttpServletRequest request, HttpServletResponse response)&nbsp; <br />20.&nbsp;&nbsp; <br />21.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws ServletException, IOException {&nbsp; <br />22.&nbsp;&nbsp; <br />23.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.setContentType("text/html");&nbsp; <br />24.&nbsp;&nbsp; <br />25.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PrintWriter out = response.getWriter();&nbsp; <br />26.&nbsp;&nbsp; <br />27.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println("&lt;!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional //EN\"&gt;");&nbsp; <br />28.&nbsp;&nbsp; <br />29.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println("&lt;HTML&gt;");&nbsp; <br />30.&nbsp;&nbsp; <br />31.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println("&nbsp; &lt;HEAD&gt;&lt;TITLE&gt;A Servlet&lt;/TITLE&gt;&lt;/HEAD&gt;");&nbsp; <br />32.&nbsp;&nbsp; <br />33.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println("&nbsp; &lt;BODY&gt;");&nbsp; <br />34.&nbsp;&nbsp; <br />35.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (emf != null) {&nbsp; <br />36.&nbsp;&nbsp; <br />37.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**创建EntityManager 对象*/&nbsp; <br />38.&nbsp;&nbsp; <br />39.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntityManager entityManager = emf.createEntityManager();&nbsp; <br />40.&nbsp;&nbsp; <br />41.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp; <br />42.&nbsp;&nbsp; <br />43.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Query query = entityManager&nbsp; <br />44.&nbsp;&nbsp; <br />45.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .createQuery("SELECT c FROM CustomerEO c");&nbsp; <br />46.&nbsp;&nbsp; <br />47.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List&lt;CustomerEO&gt; result = query.getResultList();&nbsp; <br />48.&nbsp;&nbsp; <br />49.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (CustomerEO c : result) {&nbsp; <br />50.&nbsp;&nbsp; <br />51.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(c.getId() + "," + c.getName());&nbsp; <br />52.&nbsp;&nbsp; <br />53.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />54.&nbsp;&nbsp; <br />55.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } finally {&nbsp; <br />56.&nbsp;&nbsp; <br />57.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**关闭EntityManager*/&nbsp; <br />58.&nbsp;&nbsp; <br />59.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; entityManager.close();&nbsp; <br />60.&nbsp;&nbsp; <br />61.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />62.&nbsp;&nbsp; <br />63.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />64.&nbsp;&nbsp; <br />65.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println("&nbsp; &lt;/BODY&gt;");&nbsp; <br />66.&nbsp;&nbsp; <br />67.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println("&lt;/HTML&gt;");&nbsp; <br />68.&nbsp;&nbsp; <br />69.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.flush();&nbsp; <br />70.&nbsp;&nbsp; <br />71.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.close();&nbsp; <br />72.&nbsp;&nbsp; <br />73.&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />74.&nbsp;&nbsp; <br />75.&nbsp;&nbsp;&nbsp;&nbsp; /**Servlet初始化时，创建EntityManagerFactory 对象*/&nbsp; <br />76.&nbsp;&nbsp; <br />77.&nbsp;&nbsp;&nbsp;&nbsp; public void init() throws ServletException {&nbsp; <br />78.&nbsp;&nbsp; <br />79.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (emf == null) {&nbsp; <br />80.&nbsp;&nbsp; <br />81.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emf = Persistence.createEntityManagerFactory("jpaUnit");&nbsp; <br />82.&nbsp;&nbsp; <br />83.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />84.&nbsp;&nbsp; <br />85.&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />86.&nbsp;&nbsp; <br />87.&nbsp;&nbsp;&nbsp;&nbsp; /**Servlet销毁时，关闭EntityManagerFactory对象*/&nbsp; <br />88.&nbsp;&nbsp; <br />89.&nbsp;&nbsp;&nbsp;&nbsp; public void destroy() {&nbsp; <br />90.&nbsp;&nbsp; <br />91.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (emf.isOpen())&nbsp; <br />92.&nbsp;&nbsp; <br />93.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emf.close();&nbsp; <br />94.&nbsp;&nbsp; <br />95.&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />96.&nbsp;&nbsp; <br />97. }&nbsp; <br /><br />public class TestServlet extends HttpServlet {<br /><br />private EntityManagerFactory emf;<br /><br />public TestServlet() {<br /><br />super();<br /><br />}<br /><br />public void doGet(HttpServletRequest request, HttpServletResponse response)<br /><br />throws ServletException, IOException {<br /><br />doPost(request, response);<br /><br />}<br /><br />public void doPost(HttpServletRequest request, HttpServletResponse response)<br /><br />throws ServletException, IOException {<br /><br />response.setContentType("text/html");<br /><br />PrintWriter out = response.getWriter();<br /><br />out.println("&lt;!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional //EN\"&gt;");<br /><br />out.println("&lt;HTML&gt;");<br /><br />out.println("&nbsp; &lt;HEAD&gt;&lt;TITLE&gt;A Servlet&lt;/TITLE&gt;&lt;/HEAD&gt;");<br /><br />out.println("&nbsp; &lt;BODY&gt;");<br /><br />if (emf != null) {<br /><br />/**创建EntityManager 对象*/<br /><br />EntityManager entityManager = emf.createEntityManager();<br /><br />try {<br /><br />Query query = entityManager<br /><br />.createQuery("SELECT c FROM CustomerEO c");<br /><br />List&lt;CustomerEO&gt; result = query.getResultList();<br /><br />for (CustomerEO c : result) {<br /><br />System.out.println(c.getId() + "," + c.getName());<br /><br />}<br /><br />} finally {<br /><br />/**关闭EntityManager*/<br /><br />entityManager.close();<br /><br />}<br /><br />}<br /><br />out.println("&nbsp; &lt;/BODY&gt;");<br /><br />out.println("&lt;/HTML&gt;");<br /><br />out.flush();<br /><br />out.close();<br /><br />}<br /><br />/**Servlet初始化时，创建EntityManagerFactory 对象*/<br /><br />public void init() throws ServletException {<br /><br />if (emf == null) {<br /><br />emf = Persistence.createEntityManagerFactory("jpaUnit");<br /><br />}<br /><br />}<br /><br />/**Servlet销毁时，关闭EntityManagerFactory对象*/<br /><br />public void destroy() {<br /><br />if (emf.isOpen())<br /><br />emf.close();<br /><br />}<br /><br />}<br /><br /><br /><br />使用这种方式创建EntityManagerFactory对象需要注意以下几个问题。<br /><br />可以看到，这里的EntityManagerFactory对象不是通过注入获得的，而是通过Persistence类中的静态方法createEntityManagerFactory来创建的。<br /><br />&#8212; 正因为EntityManagerFactory对象是手动创建的，所以在不再使用时，一定要调用close()方法手动关闭。<br /><br />11.1.4.3&nbsp; J2SE环境中获得<br /><br />在J2SE环境中，获得应用托管的EntityManager对象只能通过手动创建的方式，而不能使用注释的方式，与Web容器中不使用注释的方法相同，都是通过Persistence类中createEntityManagerFactory来创建的。<br /><br />例如，下面代码为J2SE环境中获得应用托管EntityManager对象的方法。<br /><br />1. public class CustomerClient {&nbsp; <br />2.&nbsp;&nbsp; <br />3.&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String[] args) {&nbsp; <br />4.&nbsp;&nbsp; <br />5.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /** 创建EntityManagerFactory对象 */&nbsp; <br />6.&nbsp;&nbsp; <br />7.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntityManagerFactory emf = Persistence&nbsp; <br />8.&nbsp;&nbsp; <br />9.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .createEntityManagerFactory("jpaUnit");&nbsp; <br />10.&nbsp;&nbsp; <br />11.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /** 创建entityManager对象 */&nbsp; <br />12.&nbsp;&nbsp; <br />13.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntityManager entityManager = emf.createEntityManager();&nbsp; <br />14.&nbsp;&nbsp; <br />15.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Query query = entityManager.createQuery("SELECT c FROM CustomerEO c");&nbsp; <br />16.&nbsp;&nbsp; <br />17.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List&lt;CustomerEO&gt; result = query.getResultList();&nbsp; <br />18.&nbsp;&nbsp; <br />19.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (CustomerEO c : result) {&nbsp; <br />20.&nbsp;&nbsp; <br />21.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(c.getId() + "," + c.getName());&nbsp; <br />22.&nbsp;&nbsp; <br />23.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />24.&nbsp;&nbsp; <br />25.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /** 关闭entityManager对象 */&nbsp; <br />26.&nbsp;&nbsp; <br />27.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; entityManager.close();&nbsp; <br />28.&nbsp;&nbsp; <br />29.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /** 关闭EntityManagerFactory对象 */&nbsp; <br />30.&nbsp;&nbsp; <br />31.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emf.close();&nbsp; <br />32.&nbsp;&nbsp; <br />33.&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />34.&nbsp;&nbsp; <br />35. }&nbsp; <br /><br />public class CustomerClient {<br /><br />public static void main(String[] args) {<br /><br />/** 创建EntityManagerFactory对象 */<br /><br />EntityManagerFactory emf = Persistence<br /><br />.createEntityManagerFactory("jpaUnit");<br /><br />/** 创建entityManager对象 */<br /><br />EntityManager entityManager = emf.createEntityManager();<br /><br />Query query = entityManager.createQuery("SELECT c FROM CustomerEO c");<br /><br />List&lt;CustomerEO&gt; result = query.getResultList();<br /><br />for (CustomerEO c : result) {<br /><br />System.out.println(c.getId() + "," + c.getName());<br /><br />}<br /><br />/** 关闭entityManager对象 */<br /><br />entityManager.close();<br /><br />/** 关闭EntityManagerFactory对象 */<br /><br />emf.close();<br /><br />}<br /><br />}<br /><br /><br />但是，在J2SE环境中使用JPA需要将实现的JPA的第三方类包和数据库的驱动包，设置到当前的运行环境下。<br /><br />例如，在Eclipse中创建一个Java项目，需要将JPA实现者的类库（这里以Hibernate为例）和MySQL的数据库连接包添加到构建路径中，如图11-2所示。<br /><br />11.1.5&nbsp; ThreadLocal的使用<br /><br />对于在Web容器中使用EntityManager对象，这里需要做一些改进，才能更安全。读者应该了解，Servlet是非线程安全的，所以需要改变获得EntityManager对象的方式，这里笔者建议使用ThreadLocal类。<br /><br />ThreadLocal就是为每一个使用某变量的线程都提供一个该变量值的副本，使每一个线程都可以独立地改变自己的副本，而不会和其他线程的副本冲突。从线程的角度看，就好像每一个线程都完全拥有一个该变量，这就解决了Servlet非线程安全的问题。<br /><br />首先编写一个EntityManagerHelper类，代码如下所示。<br /><br />1. public class EntityManagerHelper {&nbsp; <br />2.&nbsp;&nbsp; <br />3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />4.&nbsp;&nbsp; <br />5.&nbsp;&nbsp;&nbsp;&nbsp; private static final EntityManagerFactory emf;&nbsp; <br />6.&nbsp;&nbsp; <br />7.&nbsp;&nbsp;&nbsp;&nbsp; private static final ThreadLocal&lt;EntityManager&gt; threadLocal;&nbsp; <br />8.&nbsp;&nbsp; <br />9.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />10.&nbsp;&nbsp; <br />11.&nbsp;&nbsp;&nbsp;&nbsp; /**初始化*/&nbsp; <br />12.&nbsp;&nbsp; <br />13.&nbsp;&nbsp;&nbsp;&nbsp; static {&nbsp; <br />14.&nbsp;&nbsp; <br />15.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; emf = Persistence.createEntityManagerFactory("jpaUnit");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />16.&nbsp;&nbsp; <br />17.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; threadLocal = new ThreadLocal&lt;EntityManager&gt;();&nbsp; <br />18.&nbsp;&nbsp; <br />19.&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />20.&nbsp;&nbsp; <br />21.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />22.&nbsp;&nbsp; <br />23.&nbsp;&nbsp;&nbsp;&nbsp; /**通过threadLocal 获得EntityManager 对象*/&nbsp; <br />24.&nbsp;&nbsp; <br />25.&nbsp;&nbsp;&nbsp;&nbsp; public static EntityManager getEntityManager() {&nbsp; <br />26.&nbsp;&nbsp; <br />27.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntityManager manager = threadLocal.get();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />28.&nbsp;&nbsp; <br />29.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (manager == null || !manager.isOpen()) {&nbsp; <br />30.&nbsp;&nbsp; <br />31.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; manager = emf.createEntityManager();&nbsp; <br />32.&nbsp;&nbsp; <br />33.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; threadLocal.set(manager);&nbsp; <br />34.&nbsp;&nbsp; <br />35.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />36.&nbsp;&nbsp; <br />37.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return manager;&nbsp; <br />38.&nbsp;&nbsp; <br />39.&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />40.&nbsp;&nbsp; <br />41.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />42.&nbsp;&nbsp; <br />43.&nbsp;&nbsp;&nbsp;&nbsp; /**关闭EntityManager 对象*/&nbsp; <br />44.&nbsp;&nbsp; <br />45.&nbsp;&nbsp;&nbsp;&nbsp; public static void closeEntityManager() {&nbsp; <br />46.&nbsp;&nbsp; <br />47.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntityManager em = threadLocal.get();&nbsp; <br />48.&nbsp;&nbsp; <br />49.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; threadLocal.set(null);&nbsp; <br />50.&nbsp;&nbsp; <br />51.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (em != null) em.close();&nbsp; <br />52.&nbsp;&nbsp; <br />53.&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />54.&nbsp;&nbsp; <br />55.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />56.&nbsp;&nbsp; <br />57.&nbsp;&nbsp;&nbsp;&nbsp; public static void beginTransaction() {&nbsp; <br />58.&nbsp;&nbsp; <br />59.&nbsp;&nbsp;&nbsp;&nbsp; getEntityManager().getTransaction().begin();&nbsp; <br />60.&nbsp;&nbsp; <br />61.&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />62.&nbsp;&nbsp; <br />63.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />64.&nbsp;&nbsp; <br />65.&nbsp;&nbsp;&nbsp;&nbsp; public static void commit() {&nbsp; <br />66.&nbsp;&nbsp; <br />67.&nbsp;&nbsp;&nbsp;&nbsp; getEntityManager().getTransaction().commit();&nbsp; <br />68.&nbsp;&nbsp; <br />69.&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />70.&nbsp;&nbsp; <br />71.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />72.&nbsp;&nbsp; <br />73.&nbsp;&nbsp;&nbsp;&nbsp; public static Query createQuery(String query) {&nbsp; <br />74.&nbsp;&nbsp; <br />75.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return getEntityManager().createQuery(query);&nbsp; <br />76.&nbsp;&nbsp; <br />77.&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />78.&nbsp;&nbsp; <br />79.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />80.&nbsp;&nbsp; <br />81. }&nbsp; <br /><br />public class EntityManagerHelper {<br /><br /><br /><br />private static final EntityManagerFactory emf;<br /><br />private static final ThreadLocal&lt;EntityManager&gt; threadLocal;<br /><br /><br /><br />/**初始化*/<br /><br />static {<br /><br />emf = Persistence.createEntityManagerFactory("jpaUnit");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /><br />threadLocal = new ThreadLocal&lt;EntityManager&gt;();<br /><br />}<br /><br /><br /><br />/**通过threadLocal 获得EntityManager 对象*/<br /><br />public static EntityManager getEntityManager() {<br /><br />EntityManager manager = threadLocal.get();&nbsp;&nbsp;&nbsp;&nbsp; <br /><br />if (manager == null || !manager.isOpen()) {<br /><br />manager = emf.createEntityManager();<br /><br />threadLocal.set(manager);<br /><br />}<br /><br />return manager;<br /><br />}<br /><br /><br /><br />/**关闭EntityManager 对象*/<br /><br />public static void closeEntityManager() {<br /><br />EntityManager em = threadLocal.get();<br /><br />threadLocal.set(null);<br /><br />if (em != null) em.close();<br /><br />}<br /><br /><br /><br />public static void beginTransaction() {<br /><br />getEntityManager().getTransaction().begin();<br /><br />}<br /><br /><br /><br />public static void commit() {<br /><br />getEntityManager().getTransaction().commit();<br /><br />} <br /><br /><br /><br />public static Query createQuery(String query) {<br /><br />return getEntityManager().createQuery(query);<br /><br />}<br /><br /><br /><br />}<br /><br /><br /><br />这样经过改进后，在Servlet中创建EntityManager对象的方法修改为如下所示。<br /><br />1. public class TestServlet extends HttpServlet {&nbsp; <br />2.&nbsp;&nbsp; <br />3.&nbsp;&nbsp;&nbsp;&nbsp; public TestServlet() {&nbsp; <br />4.&nbsp;&nbsp; <br />5.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super();&nbsp; <br />6.&nbsp;&nbsp; <br />7.&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />8.&nbsp;&nbsp; <br />9.&nbsp;&nbsp;&nbsp;&nbsp; public void doPost(HttpServletRequest request, HttpServletResponse response)&nbsp; <br />10.&nbsp;&nbsp; <br />11.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws ServletException, IOException {&nbsp; <br />12.&nbsp;&nbsp; <br />13.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntityManager entityManager = EntityManagerHelper.getEntityManager();&nbsp; <br />14.&nbsp;&nbsp; <br />15.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp; <br />16.&nbsp;&nbsp; <br />17.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Query query = entityManager&nbsp; <br />18.&nbsp;&nbsp; <br />19.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .createQuery("SELECT c FROM CustomerEO c");&nbsp; <br />20.&nbsp;&nbsp; <br />21.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List&lt;CustomerEO&gt; result = query.getResultList();&nbsp; <br />22.&nbsp;&nbsp; <br />23.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (CustomerEO c : result) {&nbsp; <br />24.&nbsp;&nbsp; <br />25.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(c.getId() + "," + c.getName());&nbsp; <br />26.&nbsp;&nbsp; <br />27.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />28.&nbsp;&nbsp; <br />29.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } finally {&nbsp; <br />30.&nbsp;&nbsp; <br />31.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**关闭EntityManager*/&nbsp; <br />32.&nbsp;&nbsp; <br />33.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntityManagerHelper.closeEntityManager();&nbsp; <br />34.&nbsp;&nbsp; <br />35.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />36.&nbsp;&nbsp; <br />37.&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />38.&nbsp;&nbsp; <br />39. }&nbsp;</div></td></tr></tbody></table><br /><img src ="http://www.blogjava.net/jesson2005/aggbug/380881.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesson2005/" target="_blank">张金鹏</a> 2012-06-15 21:36 <a href="http://www.blogjava.net/jesson2005/articles/380881.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JPA EntityManager详解(一)</title><link>http://www.blogjava.net/jesson2005/articles/380880.html</link><dc:creator>张金鹏</dc:creator><author>张金鹏</author><pubDate>Fri, 15 Jun 2012 13:34:00 GMT</pubDate><guid>http://www.blogjava.net/jesson2005/articles/380880.html</guid><wfw:comment>http://www.blogjava.net/jesson2005/comments/380880.html</wfw:comment><comments>http://www.blogjava.net/jesson2005/articles/380880.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesson2005/comments/commentRss/380880.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesson2005/services/trackbacks/380880.html</trackback:ping><description><![CDATA[<div class="tit">JPA EntityManager详解(一)</div>
<table style="table-layout: fixed; width: 100%">
<tbody>
<tr>
<td>
<div class="cnt" id="blog_text">持久化上下文（Persistence Contexts）的相关知识，内容包括如何从Java EE容器中创建EntityManager对象、如何从Java SE中创建EntityManager对象、持久化上下文与事务（Transction）的关系，以及实体管理器工厂（Entity Manager Factory）的相关内容。 <br />通过本章的学习，读者将深入掌握JPA中有关持久化上下文、事务处理的相关知识，从而能够更加深入地应用JPA。 <br /><br /><br />11.1 获得EntityManager对象 <br /><br />那么如何获得EntityManager对象呢？这又是JPA中另外一个很重要的问题。 <br /><br /><br />11.1.1&nbsp; Java EE环境与J2SE环境 <br /><br />在详细讲述EntityManager对象之前，读者首先要分清楚两个概念，即Java EE环境与J2SE环境。因为在本章后面的学习中要经常提到这两个概念，所以读者一定要先理解它们，为以后的学习打好基础。 <br /><br /><br />&#8212; Java EE环境，包括EJB容器和Web容器。 <br /><br />（1）Web容器：只运行Web应用的容器，例如Tomcat就是开源的Web容器，它可以运行JSP、Servlet等。 <br /><br />（2）EJB容器：运行在EJB组件的容器，提供EJB组件的状态管理、事务管理、线程管理、远程数据资源访问、连接管理和安全性管理等系统级服务。例如JBoss为EJB容器和Web容器（Web容器是集成了Tomcat）结合。 <br /><br />部署在EJB容器中的JAR包都可以认为是运行在EJB容器中。但JBoss中的Web应用，比如war包中的类就不是运行在EJB容器中，而是运行在Web容器中。 <br /><br />&#8212; J2SE环境 <br /><br />最普通Java运行环境，例如一个HelloWorld的Java程序就是运行在J2SE的环境中，通常使用main入口方法作为程序启动的触发。 <br /><br />如图11-1所示，它说明了Java EE与J2SE环境的关系。 <br /><br />11.1.2&nbsp; 两种类型的EntityManager对象 <br /><br />根据EntityManager对象的管理方式，可以有以下两种类型。 <br /><br />&#8212; 容器托管的（container-managed）EntityManager对象 <br /><br />容器托管的EntityManager对象最简单，程序员不需要考虑EntityManager连接的释放，以及事务等复杂的问题，所有这些都交 给容器去管理。容器托管的EntityManager对象必须在EJB容器中运行，而不能在Web容器和J2SE的环境中运行。本书前面讲述的 EntityManager对象都是通过注入 @PersistenceContext注释来获得的，其实，这种获得EntityManager对象的方式就是容器托管的。 <br /><br />&#8212; 应用托管的（application-managed）EntityManager对象 <br /><br />应用托管的EntityManager对象，程序员需要手动地控制它的释放和连接、手动地控制事务等。但这种获得应用托管的 EntityManager对象的方式，不仅可以在EJB容器中应用，也可以使 JPA脱离EJB容器，而与任何的Java环境集成，比如说Web容器、J2SE环境等。所以从某种角度上来说，这种方式是JPA能够独立于EJB环境运 行的基础。 <br /><br />理想状态下，最好是选用容器托管的EntityManager对象的方式，但在特殊的环境下，还是需要使用应用托管的EntityManager对象这种方式。 <br /><br />正是因为应用托管的EntityManager对象的连接释放、事务控制比较复杂，所以在使用时涉及的相关内容比较多，这些内容将在本章后面部分详细讲述，这里读者应对两种方式有一个大致的了解，两种EntityManager对象类型的比较如表11-1所示。 <br /><br />表11-1&nbsp; 容器托管与应用托管的EntityManager对象对比 <br /><br />比较内容 <br /><br />容器托管的（container-managed）EntityManager对象 <br /><br />应用托管的（application-managed）EntityManager对象 <br /><br />获得方式 <br /><br />两种方式：1 @PersistenceContex注入 2 JNDI获得 <br /><br />EntityManagerFactory创建 <br /><br />支持事务 <br /><br />JTA <br /><br />JTA、RESOURCE_LOCAL <br /><br />运行环境 <br /><br />EJB容器 <br /><br />EJB容器、Web容器、J2SE环境 <br /><br />11.1.3&nbsp; 容器托管的（container-managed）EntityManager对象 <br /><br />容器托管的EntityManager对象只能运行在EJB容器中。所以可以这样理解，只有在EJB-JAR包中，才可以获得容器托管的EntityManager对象，否则只能获得应用托管的EntityManager对象。 <br /><br />在EJB容器中获得EntityManager对象主要有两种方式，即@PersistenceContext注释注入和JNDI方式获得。 <br /><br />11.1.3.1&nbsp; 通过@PersistenceContext注释注入 <br /><br />这种方式获得EntityManager对象最为常用，例如下面代码所示。 <br /><br />
<div class="dp-highlighter">
<ol class="dp-j"><li><span class="annotation">@Stateless</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;CustomerService&nbsp;</span><span class="keyword">implements</span><span>&nbsp;ICustomerService&nbsp;{&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="annotation">@PersistenceContext</span><span>(unitName&nbsp;=&nbsp;</span><span class="string">"jpaUnit"</span><span>)&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;EntityManager&nbsp;entityManager;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;List&lt;CustomerEO&gt;&nbsp;findAllCustomers()&nbsp;{&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Query&nbsp;query&nbsp;=&nbsp;entityManager.createQuery(<span class="string">"SELECT&nbsp;c&nbsp;FROM&nbsp;CustomerEO&nbsp;c"</span><span>);&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&lt;CustomerEO&gt;&nbsp;result&nbsp;=&nbsp;query.getResultList();&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span><span>&nbsp;(CustomerEO&nbsp;c&nbsp;:&nbsp;result)&nbsp;{&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(c.getId()+<span class="string">","</span><span>+c.getName());&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;result;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>}&nbsp;&nbsp;</span> </li></ol></div><pre class="java" style="display: none" name="code">@Stateless  public class CustomerService implements ICustomerService {      @PersistenceContext(unitName = "jpaUnit")      private EntityManager entityManager;      public List&lt;CustomerEO&gt; findAllCustomers() {          Query query = entityManager.createQuery("SELECT c FROM CustomerEO c");          List&lt;CustomerEO&gt; result = query.getResultList();          for (CustomerEO c : result) {              System.out.println(c.getId()+","+c.getName());          }          return result;      }  }</pre><br /><br />在使用此种方式创建EntityManager对象时，需要注意以下几个问题。 <br /><br />&#8212; @PersistenceContext注释中，其中unitName为persistence.xml文件中&lt;persistence-unit&gt;元素中的属性&#8220;name&#8221;的值，表示要初始化哪个持久化单元，如下所示。 <br /><br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Xml代码</div></div>
<ol class="dp-xml"><li><span class="tag">&lt;</span><span class="tag-name">persistence</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">persistence-unit</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"jpaUnit"</span><span>&nbsp;</span><span class="attribute">transaction-type</span><span>=</span><span class="attribute-value">"JTA"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">persistence-unit</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span class="tag">&lt;/</span><span class="tag-name">persistence</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li></ol></div><pre class="xml" style="display: none" name="code">&lt;persistence&gt;      &lt;persistence-unit name="jpaUnit" transaction-type="JTA"&gt;      &lt;/persistence-unit&gt;  &lt;/persistence&gt;</pre><br /><br />&#8212; @PersistenceContext注释中还可以配置其他的设置，它的定义如下所示。 <br /><br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码</div></div>
<ol class="dp-j"><li><span class="annotation">@Target</span><span>({TYPE,&nbsp;METHOD,&nbsp;FIELD})&nbsp;</span><span class="annotation">@Retention</span><span>(RUNTIME)&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">@interface</span><span>&nbsp;PersistenceContext{&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;name()&nbsp;<span class="keyword">default</span><span>&nbsp;</span><span class="string">""</span><span>;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;unitName()&nbsp;<span class="keyword">default</span><span>&nbsp;</span><span class="string">""</span><span>;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;PersistenceContextType&nbsp;type&nbsp;<span class="keyword">default</span><span>&nbsp;TRANSACTION;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;PersistenceProperty[]&nbsp;properties()&nbsp;<span class="keyword">default</span><span>&nbsp;{};&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>}&nbsp;&nbsp;</span> </li></ol></div><pre class="java" style="display: none" name="code">@Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME)  public @interface PersistenceContext{      String name() default "";      String unitName() default "";      PersistenceContextType type default TRANSACTION;      PersistenceProperty[] properties() default {};  }</pre><br /><br />&#8212; 其中PersistenceContextType可以设置创建EntityManager对象时，持久化上下文的作用范围，它的意义在于对有状态的Bean（Stateless Bean）可以跨事务操作实体。它主要有两种方式，定义如下所示。 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码</div></div>
<ol class="dp-j"><li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">enum</span><span>&nbsp;PersistenceContextType&nbsp;{&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;TRANSACTION,&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;EXTENDED&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>}&nbsp;&nbsp;</span> </li></ol></div><pre class="java" style="display: none" name="code">public enum PersistenceContextType {      TRANSACTION,      EXTENDED  }</pre><br /><br />默认情况下使用TRANSACTION，有关TRANSACTION方式和EXTENDED方式创建EntityManager对象的异同，将在下文中详细讲述，这里读者简单了解一下即可。 <br /><br />11.1.3.2&nbsp; 通过JNDI的方式获得 <br /><br />如果指定了@PersistenceContext注释中的name值，则设置了持久化上下文的JNDI名称。通过SessionContext可以创建EntityManager对象。 <br /><br />例如，下面代码为通过JNDI方式获得EntityManager对象。 <br /><br />
<div class="dp-highlighter">
<ol class="dp-j"><li><span class="annotation">@Stateless</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span class="annotation">@PersistenceContext</span><span>(name=</span><span class="string">"jpa"</span><span>)&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;CustomerService&nbsp;</span><span class="keyword">implements</span><span>&nbsp;ICustomerService&nbsp;{&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="annotation">@Resource</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;SessionContext&nbsp;ctx;&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;List&lt;CustomerEO&gt;&nbsp;findAllCustomers()&nbsp;{&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EntityManager&nbsp;entityManager&nbsp;=&nbsp;(EntityManager)&nbsp;ctx.lookup(<span class="string">"jpa"</span><span>);&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Query&nbsp;query&nbsp;=&nbsp;entityManager.createQuery(<span class="string">"SELECT&nbsp;c&nbsp;FROM&nbsp;CustomerEO&nbsp;c"</span><span>);&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&lt;CustomerEO&gt;&nbsp;result&nbsp;=&nbsp;query.getResultList();&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span><span>&nbsp;(CustomerEO&nbsp;c&nbsp;:&nbsp;result)&nbsp;{&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(c.getId()+<span class="string">","</span><span>+c.getName());&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;result;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>}&nbsp;&nbsp;</span> </li></ol></div><pre class="java" style="display: none" name="code">@Stateless  @PersistenceContext(name="jpa")  public class CustomerService implements ICustomerService {      @Resource      SessionContext ctx;      public List&lt;CustomerEO&gt; findAllCustomers() {          EntityManager entityManager = (EntityManager) ctx.lookup("jpa");          Query query = entityManager.createQuery("SELECT c FROM CustomerEO c");          List&lt;CustomerEO&gt; result = query.getResultList();          for (CustomerEO c : result) {              System.out.println(c.getId()+","+c.getName());          }          return result;      }  }</pre><br /><br />11.1.4&nbsp; 应用托管的（application-managed）EntityManager对象 <br /><br />应用托管的EntityManager对象，不仅可以在Java EE环境中获得，也可以应用在J2SE的环境中。但无论是在什么情况下获得的EntityManager对象，都是通过实体管理器工厂 （EntityManagerFactory）对象创建的。所以如何获得应用托管的EntityManager对象关键是 EntityManagerFactory对象如何获得。 <br /><br />下面就分别讲述在EJB容器、Web容器和J2SE环境中如何获得EntityManagerFactory对象。 <br /><br />11.1.4.1&nbsp; EJB容器中获得 <br /><br />在EJB容器中，EntityManagerFactory对象可以通过使用注入@PersistenceUnit注释获得，例如下面代码为在EJB容器中，获得应用托管的EntityManager对象的方法。 <br /><br />
<div class="dp-highlighter">
<ol class="dp-j"><li><span class="annotation">@Stateless</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;CustomerService&nbsp;</span><span class="keyword">implements</span><span>&nbsp;ICustomerService&nbsp;{&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="annotation">@PersistenceUnit</span><span>(unitName=</span><span class="string">"jpaUnit"</span><span>)&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;EntityManagerFactory&nbsp;emf;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;List&lt;CustomerEO&gt;&nbsp;findAllCustomers()&nbsp;{&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**创建EntityManager对象*/</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EntityManager&nbsp;em&nbsp;=&nbsp;emf.createEntityManager();&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Query&nbsp;query&nbsp;=&nbsp;em.createQuery(<span class="string">"SELECT&nbsp;c&nbsp;FROM&nbsp;CustomerEO&nbsp;c"</span><span>);&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&lt;CustomerEO&gt;&nbsp;result&nbsp;=&nbsp;query.getResultList();&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span><span>&nbsp;(CustomerEO&nbsp;c&nbsp;:&nbsp;result)&nbsp;{&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(c.getId()+<span class="string">","</span><span>+c.getName());&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**关闭EntityManager&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;em.close();&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;result;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>}&nbsp;&nbsp;</span> </li></ol></div><pre class="java" style="display: none" name="code">@Stateless  public class CustomerService implements ICustomerService {      @PersistenceUnit(unitName="jpaUnit")      private EntityManagerFactory emf;      public List&lt;CustomerEO&gt; findAllCustomers() {          /**创建EntityManager对象*/          EntityManager em = emf.createEntityManager();          Query query = em.createQuery("SELECT c FROM CustomerEO c");          List&lt;CustomerEO&gt; result = query.getResultList();          for (CustomerEO c : result) {              System.out.println(c.getId()+","+c.getName());          }          /**关闭EntityManager */          em.close();          return result;      }  }</pre><br />通过以上的EntityManager对象代码，可以总结出以下几个问题。 <br /><br />&#8212; 应用托管的EntityManager对象，要在代码中手动地创建和关闭，例如下面代码所示。 <br /><br />EntityManager em = emf.createEntityManager(); <br /><br />/**其他的业务逻辑*/ <br /><br />em.close(); <br /><br />这点正是与容器托管的EntityManager对象的最大不同之处。事实上，容器托管的EntityManager对象，它的创建和关闭是由容器负责管理的，所以不需要编写代码来控制。 <br /><br />&#8212; 应用托管的EntityManager对象，都是通EntityManagerFactory对象来创建的。在容器中可以通过使用注入@PersistenceUnit注释的方法实现，它的定义如下所示。 <br /><br />
<div class="dp-highlighter">
<ol class="dp-j"><li><span class="annotation">@Target</span><span>({TYPE,&nbsp;METHOD,&nbsp;FIELD})&nbsp;</span><span class="annotation">@Retention</span><span>(RUNTIME)&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">@interface</span><span>&nbsp;PersistenceUnit{&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;name()&nbsp;<span class="keyword">default</span><span>&nbsp;</span><span class="string">""</span><span>;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;unitName()&nbsp;<span class="keyword">default</span><span>&nbsp;</span><span class="string">""</span><span>;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>}&nbsp; <br /></span></li></ol><br />其中，属性unitName为persistence.xml文件中&lt;persistence-unit&gt;元素中的属性&#8220;name&#8221;的值，表示要初始化哪个持久化单元，与@PersistenceContext注释中unitName属性相同。 <br /><br />11.1.4.2&nbsp; Web容器中获得 <br /><br />在Web容器中，EntityManagerFactory对象也可以通过使用注入@PersistenceUnit注释获得。例如，下面代码为在 Servlet中，获得应用托管的EntityManager对象的方法。 /syntaxhighlighter/clipboard_new.swf"&gt; 
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j"><li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;TestServlet&nbsp;</span><span class="keyword">extends</span><span>&nbsp;HttpServlet&nbsp;{&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="annotation">@PersistenceUnit</span><span>(unitName&nbsp;=&nbsp;</span><span class="string">"jpaUnit"</span><span>)&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;EntityManagerFactory&nbsp;emf;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;TestServlet()&nbsp;{&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">super</span><span>();&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;doGet(HttpServletRequest&nbsp;request,&nbsp;HttpServletResponse&nbsp;response)&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">throws</span><span>&nbsp;ServletException,&nbsp;IOException&nbsp;{&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doPost(request,&nbsp;response);&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;doPost(HttpServletRequest&nbsp;request,&nbsp;HttpServletResponse&nbsp;response)&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">throws</span><span>&nbsp;ServletException,&nbsp;IOException&nbsp;{&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.setContentType(<span class="string">"text/html"</span><span>);&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PrintWriter&nbsp;out&nbsp;=&nbsp;response.getWriter();&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(<span class="string">"&lt;!DOCTYPE&nbsp;HTML&nbsp;PUBLIC&nbsp;\"-//W3C//DTD&nbsp;HTML&nbsp;4.01&nbsp;Transitional&nbsp;//EN\"&gt;"</span><span>);&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(<span class="string">"&lt;HTML&gt;"</span><span>);&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(<span class="string">"&nbsp;&nbsp;&lt;HEAD&gt;&lt;TITLE&gt;A&nbsp;Servlet&lt;/TITLE&gt;&lt;/HEAD&gt;"</span><span>);&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(<span class="string">"&nbsp;&nbsp;&lt;BODY&gt;"</span><span>);&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(emf&nbsp;!=&nbsp;</span><span class="keyword">null</span><span>)&nbsp;{&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**创建EntityManager&nbsp;对象*/</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EntityManager&nbsp;entityManager&nbsp;=&nbsp;emf.createEntityManager();&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">try</span><span>&nbsp;{&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Query&nbsp;query&nbsp;=&nbsp;entityManager&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.createQuery(<span class="string">"SELECT&nbsp;c&nbsp;FROM&nbsp;CustomerEO&nbsp;c"</span><span>);&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&lt;CustomerEO&gt;&nbsp;result&nbsp;=&nbsp;query.getResultList();&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span><span>&nbsp;(CustomerEO&nbsp;c&nbsp;:&nbsp;result)&nbsp;{&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(c.getId()&nbsp;+&nbsp;<span class="string">","</span><span>&nbsp;+&nbsp;c.getName());&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span class="keyword">finally</span><span>&nbsp;{&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**关闭EntityManager*/</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;entityManager.close();&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(<span class="string">"&nbsp;&nbsp;&lt;/BODY&gt;"</span><span>);&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(<span class="string">"&lt;/HTML&gt;"</span><span>);&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.flush();&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.close();&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>}&nbsp;&nbsp;</span> </li></ol></div></div></div></td></tr></tbody></table> <img src ="http://www.blogjava.net/jesson2005/aggbug/380880.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesson2005/" target="_blank">张金鹏</a> 2012-06-15 21:34 <a href="http://www.blogjava.net/jesson2005/articles/380880.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>