??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲AV噜噜一区二区三区,亚洲一区日韩高清中文字幕亚洲,激情小说亚洲色图http://www.tkk7.com/jesson2005/category/51978.htmlN文hQ乃市井一俗h也,ȝ卷书Q跨江河千里Q故甛_一游; 一两滴辛酸Q三四年学业Q五六点_墨Q七八笔买卖Q九(ji)十道人情?/description>zh-cnFri, 15 Jun 2012 15:38:15 GMTFri, 15 Jun 2012 15:38:15 GMT60JPA本地查询(Native Query)(?http://www.tkk7.com/jesson2005/articles/380885.html张金?/dc:creator>张金?/author>Fri, 15 Jun 2012 13:39:00 GMThttp://www.tkk7.com/jesson2005/articles/380885.htmlhttp://www.tkk7.com/jesson2005/comments/380885.htmlhttp://www.tkk7.com/jesson2005/articles/380885.html#Feedback0http://www.tkk7.com/jesson2005/comments/commentRss/380885.htmlhttp://www.tkk7.com/jesson2005/services/trackbacks/380885.htmlJPA本地查询(Native Query)(?
2010-01-20 10:52

最后一U映类型,是实体与标量值的l合

 

    @SqlResultSetMapping

    (

       name="ReturnOrderListWithPartEntityPartScalarType",

       entities=

       {

           @EntityResult

           (

              entityClass=entity.Order.class,

              fields=

              {

               @FieldResult(name="id",column="order_id"),

               @FieldResult(name="date",column="order_creation_date"),

               @FieldResult(name="desc",column="order_description"),

              @FieldResult(name="sum",column="order_sum_total")

              }

           ),

          

           @EntityResult

           (

              entityClass=entity.Customer.class,

              discriminatorColumn="customer_type",

              fields=

              {

                  @FieldResult(name="id",column="customer_id"),

                  @FieldResult(name="ctype",column="customer_type")

              }

           )

       },

       columns=

       {

           @ColumnResult(name="customer_name")

       }

    )

 

我们结果集中与订单有关的保存进Order EntityQ把?span style="color: black">Customer有关的,?span style="color: black">id?span style="color: black">customer type 保存q?span style="color: black">Customer EntityQ把customer name保存q标量?

 

l过q行试E序Q得?/span>

 

*****ReturnOrderListWithPartEntityPartScalarType*****

entity.Order@48edb5 entity.GoldenCustomer@1ee2c2c   John Smith

entity.Order@1402d5a entity.GoldenCustomer@1ee2c2c   John Smith

entity.Order@1e13e07 entity.GoldenCustomer@1ee2c2c   John Smith

 

lg所qͼ我们可以采取多种resultset映射机制来保存用本地查询得到的结果集Q具体采取哪U要看具体的情况Q要l箋了解q方面的知识?/p>




]]>
JPA本地查询(Native Query)(一)http://www.tkk7.com/jesson2005/articles/380883.html张金?/dc:creator>张金?/author>Fri, 15 Jun 2012 13:38:00 GMThttp://www.tkk7.com/jesson2005/articles/380883.htmlhttp://www.tkk7.com/jesson2005/comments/380883.htmlhttp://www.tkk7.com/jesson2005/articles/380883.html#Feedback0http://www.tkk7.com/jesson2005/comments/commentRss/380883.htmlhttp://www.tkk7.com/jesson2005/services/trackbacks/380883.htmlJPA本地查询(Native Query)(一)
2010-01-20 10:49

JPA支持本地查询Q所谓本地查询,是使用原生?span style="color: rgb(0,0,0)">sql语句Q根据数据库的不同,?span style="color: rgb(0,0,0)">sql的语法或l构斚w可能有所区别Q进行查询数据库的操作?/span>

 

本地查询主要使用EntityManager接口里的Ҏ(gu)Q?/span>

public interface EntityManager {
public void persist(Object entity);
public <T> T find(Class <T> entityClass, Object primaryKey);
public <T> T getReference(Class <T> entityClass, Object primaryKey);
public <T> T merge(T entity);
public void remove(Object entity);
public void lock(Object entity, LockModeType lockMode);

public void refresh(Object entity);
public boolean contains(Object entity);
public void clear( );

public void joinTransaction( );
public void flush( );
public FlushModeType getFlushMode( );
public void setFlushMode(FlushModeType type);

public Query createQuery(String queryString);
public Query createNamedQuery(String name);

  
public Query createNativeQuery(String sqlString);
public Query createNativeQuery(String sqlString, String resultSetMapping);
public Query createNativeQuery(String sqlString, Class resultClass);


   public Object getDelegate( );

public void close( );
public boolean isOpen( );
}

 

?span style="color: rgb(0,0,0)"> createNativeQueryҎ(gu)的三UŞ式,但用q个Ҏ(gu)的缺Ҏ(gu)Q要查询的sql语句?qing)返回结果集cd传递进厅R还有一U方法是使用createNamedQueryQ这样就可以避免在这里直接写?span style="color: rgb(0,0,0)">sql语句以及(qing)q回的结果集cd{参敎ͼ而可以在相关?span style="color: rgb(0,0,0)">Entityc里对这些信息进行配|?/span>

 

//q里只是传递进M?span style="color: rgb(153,153,153)">string?/span>

Query q = em.createNamedQuery("ReturnOrderListWithFullScalarType");

//q里是设定在sql中所需的参?/p>

q.setParameter(1, customer.getId());

//得到l果?/p>

List orderList = q.getResultList();

 

 

q个查询主要是根据用L(fng)id 来获取他名下的所有订单。所以,在实体类 Order中,加入相关?span style="color: rgb(0,0,0)">native query annotation.

 

@NamedNativeQueries

(

    {

       @NamedNativeQuery(

           name="ReturnOrderListWithFullScalarType",

              query="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,

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",

           resultSetMapping="ReturnOrderListWithFullScalarType"),

        。。。。。。。。。。。。。可能还有更多的本地查询讄

}

)

 

@NamedNativeQueries 如果在一个实体类中有多个NamedNativeQuery的话Q必M用该Ҏ(gu)Qƈ且将单个?span style="color: rgb(0,0,0)">NamedNativeQuery都作?span style="color: rgb(0,0,0)">NamedNativeQueries数组中的一个元素?/span>

@NamedNativeQueryQ在q里讄关于该本地查询的信息?span style="color: rgb(0,0,255)">name表示传递进EntityManager.createNamedQuery(“name”)的参敎ͼquery表示实施本地查询?span style="color: rgb(0,0,0)">sql语句Q?span style="color: rgb(0,0,255)">resultSetMapping表示q回l果集的映射方式。它的意思就是结果集以哪种形式来保存?/span>

 

接着Q就要设|这个结果集的映方式了?/span>

 

@SqlResultSetMappings(

{

    @SqlResultSetMapping

    (

       name="ReturnOrderListWithFullScalarType",

       entities={},

       columns=

       {

           @ColumnResult(name="order_id"),

           @ColumnResult(name="order_creation_date"),

           @ColumnResult(name="order_description"),

           @ColumnResult(name="order_sum_total"),

           @ColumnResult(name="customer_id"),

           @ColumnResult(name="customer_name")

       }

    ),

       。。。。。。。。。。。。。可能还有更多的l果集映设|?/p>

})

针对每一个本地查询的q回|都有一个结果集和它映射。它可以q回

1. 实体Q包括不同类型的实体Q即多个实体Q?span style="color: rgb(0,0,0)"> Entity

2. 标量?span style="color: rgb(0,0,0)"> Scalar

3. 实体与标量值的l合 Entity+Scalar

 

默认情况下,JPA假设原生sql查询?span style="color: rgb(0,0,0)">select语句会(x)Q?/span>

1.      q回一个实体类?/span>

2.      包含与返回的实体的所有字D|属性相对应的所有列Q即列名和实体属?span style="color: rgb(0,0,0)">/字段名一?/span>

3.      查询中没有用列名别名Q?span style="color: rgb(0,0,0)">column aliasQ即没有?span style="color: rgb(0,0,0)"> AS 指定别名

 

@SqlResultSetMappingsQ如果在一个实体类中有多个@NamedNativeQuery的话Q必然就有多个结果集映射@SqlResultSetMapping。在q种情况下,必须使用该批注,q且单个的SqlResultSetMapping都作?span style="color: rgb(0,0,0)">SqlResultSetMappings数组中的一个元素?/span>

@SqlResultSetMappingQ关于结果集映射的详l信息?/span>

name 表示该结果集映射的名字,?span style="color: rgb(0,0,0)">@NamedNativeQuery中的resultSetMapping="ReturnOrderListWithFullScalarType"的值相对应?/span>

entities表示查询l果集会(x)被映进实体Q如果有p所有返回的实体一一列出Q这里我们将l果集全部映进标量Q所?span style="color: rgb(0,0,0)">entities属性是个空数组Q?/span>

columns表示被映射q标量的l果集中的各个列?/span>

 

q里要说一下标量(ScalarQ这个概c在物理学上Q标量与矢量Q?span>VectorQ是怺对应的,矢量是既有方向又有大的量,而标量是只有大小的量。在此处Q?span>Scalar的含义与物理学上的定义差不多Q?span>Scalar可以认ؓ(f)是一个没有属?span>/Ҏ(gu)的单U的帔R(可以惌?span>java数据cd?span>primitive type)Q而与它相对的则是有方?span>/属性的对象(object type)。那么采用这U映机Ӟ我们从数据库取来的每一条记录的每一个字D,仅仅是被单纯的作Z个常量,保存在每一?span>columnResult中?/span>

 

@ ColumnResultQ就是指?span style="color: rgb(0,0,0)">sql语句中,哪些查询的列保存进来。每一?span style="color: rgb(0,0,0)">@ColumnResult对应一个列Q?/span>name="order_id" Q注意,如果?span style="color: rgb(0,0,0)">select的时候,?span style="color: rgb(0,0,0)">AS 制定了列的别名,“order_id” 则表C的是别名?/span>

 

q种映射方式比较单,我们可以推测Q得到的l果?span style="color: rgb(0,0,0)">List中,数据?x)是q样Q?/span>

[ {“?span style="color: rgb(0,0,0)">1”, “?span style="color: rgb(0,0,0)">2”, “?span style="color: rgb(0,0,0)">3”, …},  {“?span style="color: rgb(0,0,0)">1”, “?span style="color: rgb(0,0,0)">2”, “?span style="color: rgb(0,0,0)">3”, …}, …… ]

 

l过q行试E序Q得C我们的推?/span>

 

 

*****ReturnOrderListWithFullScalarType*****

52 2009-05-27 00:00:00.0    This is an order creation example. 36817.0    39 John Smith

55 2009-05-27 00:00:00.0    This is an order creation example. 3347.0 39 John Smith

……

 

结果集全部映射q标量,是比较简单的一U做法,在SqlResultSetMapping



]]>
JPA本地查询(Native Query)(?http://www.tkk7.com/jesson2005/articles/380884.html张金?/dc:creator>张金?/author>Fri, 15 Jun 2012 13:38:00 GMThttp://www.tkk7.com/jesson2005/articles/380884.htmlhttp://www.tkk7.com/jesson2005/comments/380884.htmlhttp://www.tkk7.com/jesson2005/articles/380884.html#Feedback0http://www.tkk7.com/jesson2005/comments/commentRss/380884.htmlhttp://www.tkk7.com/jesson2005/services/trackbacks/380884.htmlJPA本地查询(Native Query)(?
2010-01-20 10:49

OKQ现在对同一个查询,再把l果集全部映进实体对象?/span>

 

首先

@NamedNativeQueries

(

    {

       @NamedNativeQuery(

           name="ReturnOrderListWithFullEntityType",

              query="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,

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",

           resultSetMapping="ReturnOrderListWithFullEntityType"),

        。。。。。。。。。。。。。可能还有更多的本地查询讄

}

)

改变本地查询?span style="color: rgb(0,0,0)">resultSetMapping

 

    @SqlResultSetMapping

    (

       name="ReturnOrderListWithFullEntityType",

       entities=

       {

           @EntityResult

           (

              entityClass=entity.Order.class,

              fields=

              {

    @FieldResult(name="id",column="order_id"),

                         @FieldResult(name="date",column="order_creation_date"),

                  @FieldResult(name="desc",column="order_description"),

    @FieldResult(name="sum",column="order_sum_total")

              }

           ),

 

           @EntityResult

           (

              entityClass=entity.Customer.class,

              discriminatorColumn="customer_type",

              fields=

              {

                  @FieldResult(name="id",column="customer_id"),

                  @FieldResult(name="name",column="customer_name")

              }

           )

       },

       columns={}

    )

 

entities属性是一个包含与q回l果集相映射的所有实体的一个数l。这条查询得C订单和用L(fng)信息Q所以,与结果集映射的实体,应该是Order?span style="color: rgb(0,0,0)">Customer?/span>

每一个映实体用@EntityResult表示Q?span style="color: rgb(0,0,255)">entityClass表示实体c,fields表示该实体类中的属性,与查询结果中的哪些个列相映射。而每一?#8220;属?span style="color: rgb(0,0,0)"><->?#8221;的映关p,又保存在@FieldResult里面?span style="color: rgb(0,0,255)">name是实体属性,column是查询列Q或列别名)

 

要注意的是,如果要将l果集映到实体对象Q则

1Q?span style="color: rgb(0,0,0)">Select 语句中必d含实体所映射的表中的PKQ也是 select o.id as order_id

 

2. 反过来,“属?span style="color: rgb(0,0,0)"><->?#8221;的映,也必d表的PK映射到实体类的用@Id annotationҎ(gu)的字D|属性上?/span>

 

否则Q?span style="color: rgb(0,0,0)">JPA׃(x)抛出一?span style="color: rgb(0,0,0)">exception

oracle.toplink.essentials.exceptions.QueryException

Exception Description: The primary key read from the row [DatabaseRecord(

    orders.ID => null

    orders.CREATE_DATE => 2009-05-27 00:00:00.0

    orders.SUM_PRICE => 36817.0

    orders.DESCRIPTION => This is an order creation example.

    orders.cust_id => null)] during the execution of the query was detected to be null. Primary keys must not contain null.

 

 

 

 

 

再看一下关?span style="color: rgb(0,0,0)">Customer实体的映,?span style="color: rgb(0,0,0)">Order不一L(fng)地方Q是discriminatorColumn="customer_type" (可能为列别名)

加上q个属性的原因是,CustomercL一个父c,以供其他子类l承Q?span style="color: rgb(0,0,0)">J PA的内在多态性机制将?x)获取?span style="color: rgb(0,0,0)">Customer的实际类型。根?span style="color: rgb(0,0,0)">J PA @InheritanceҎ(gu)Q得知,父类实体的表中必L一个字D(默认?span style="color: rgb(0,0,0)">DTYPEQ来表示各个子类的类型。所以当要将查询l果集保存ؓ(f)实体的时候,它必要知道你所保存的这?span style="color: rgb(0,0,0)">Customer实体到底是哪U类型?/span>

所以,你还必须?span style="color: rgb(0,0,0)">select子句中取得这?span style="color: rgb(0,0,0)">Discrimator Type的字Dc?/span>

否则又会(x)抛出异常Q?span style="color: rgb(0,0,0)"> 

oracle.toplink.essentials.exceptions.QueryException

Exception Description: Custom SQL failed to provide descriminator column : , as defined in SQLResultSetMapping : ReturnOrderListWithFullEntityType.

或者:(x)

oracle.toplink.essentials.exceptions.QueryException

Exception Description: Custom SQL failed to provide descriminator column : customer_type, as defined in SQLResultSetMapping : ReturnOrderListWithPartEntityPartScalarType.

 

 

通过q种映射方式Q我们可以推,得到的结果集List中,数据?x)是q样Q?/span>

[ {“Order对象1”, “Customer对象1”}, {“Order对象2”, “Customerr对象2”}, …… ]

 

l过q行试E序Q得C我们的推?/span>

 

*****ReturnOrderListWithFullEntityType*****

entity.Order@48edb5 entity.GoldenCustomer@1ee2c2c  

entity.Order@1402d5a entity.GoldenCustomer@1ee2c2c  

entity.Order@1e13e07 entity.GoldenCustomer@1ee2c2c  

entity.Order@9cfec1 entity.GoldenCustomer@1ee2c2c  

entity.Order@747fa2 entity.GoldenCustomer@1ee2c2c  

……

看来的确是保存了对象Q而且注意W二个对象不是Customer而是GoldenCustomerQ这说明QJPA自动数据映进了GoldenCustomer实体Q尽我们用的是Customer实体q行保存 “entityClass=entity.Customer.class”Q?/p>




]]>
createNativeQuery原生Q命名查?/title><link>http://www.tkk7.com/jesson2005/articles/380882.html</link><dc:creator>张金?/dc:creator><author>张金?/author><pubDate>Fri, 15 Jun 2012 13:37:00 GMT</pubDate><guid>http://www.tkk7.com/jesson2005/articles/380882.html</guid><wfw:comment>http://www.tkk7.com/jesson2005/comments/380882.html</wfw:comment><comments>http://www.tkk7.com/jesson2005/articles/380882.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/jesson2005/comments/commentRss/380882.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/jesson2005/services/trackbacks/380882.html</trackback:ping><description><![CDATA[<div id="1661661" class="tit">createNativeQuery原生Q命名查?/div> <div id="6116611" class="date">2010-01-20 10:27</div> <table style="table-layout: fixed; width: 100%"> <tbody> <tr> <td> <div id="6661611" class="cnt" id="blog_text"> <p>9.3.原生查询<br />EJB QL中富有大量的查询语句q且基本上能W合你的l大多数的查询需?有时,你想要用特定厂商提供的数据库上的专有能?<br />实体理服务提供了一个方法来建立原生的SQL查询q且映射他们C的对象上.原生查询能反回实?栏位?或者两者的l合.EntityManager接口有三U方法来建立原生查询:一U返回标量?一U是q回实体cd,最后一U是定义一个复杂的l果?它能映射到多个实体的混合和标量?<br />你可以进行JDBC的连接通过javax.sql.DataSource,使用@Resource注入和执行你的SQL语句.要意识到你所做的改变不会(x)被当前的持久化上下文所反映.</p> <p>9.3.1. 标量原生查询<br />Query createNativeQuery(String sql)<br />q将建立一个原生查询返回一个标量结?它需要一个参?你的原生SQL.它执行ƈ且返回结果集同EJB QL相同的Ş?q回标量?</p> <p>9.3.2.单的实体原生查询<br />Query createNativeQuery(String sql, Class entityClass) <br />一个简单的原生查询通过一个SQL语句和隐式的映像C个实?映射元数据ؓ(f)基础的一个实?它认为原生查询的l果集中的栏完全匹配实体的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 />q个实体理Ҏ(gu)允许你有一个复杂的映射为原生SQL.你可以同时返回多个实体和标量?mappingName 参数参考@javax.persistence.SqlResultSetMapping定义.q个Ҏ(gu)用来定义一个怎能h询原生结果的钓子到O/R模型.如果q回的栏位名与批注映的属性不匚w,你可以提代一个字D到栏位的映ؓ(f)他们,使用@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 />让我们做一pd的例子表C?x)如何工?</p> <p>9.3.3.1. 使用多个实体的原生查?br />@Entity<br />@SqlResultSetMapping(name="customerAndCreditCardMapping",<br /><a href="mailto:entities=%7B@EntityResult%28entityClass=Customer.class">entities={@EntityResult(entityClass=Customer.class</a>),<br />@EntityResult(entityClass=CreditCard.class,<br /><a href="mailto:fields=%7B@FieldResult%28name=%22id">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 />因ؓ(f)l果集返回多个实体类?我们必需使用一个@SqlResultSetMapping.q个Ҏ(gu)可以被放在一个实体类或方法上.entities( )属性用来设|@EntityResultҎ(gu)l成的队?每一个@EntityResult注释指定要通过原生SQL查询q回的实?<br />@javax.persistence.FieldResult注释用来明确查询中与实体属性对应的映射栏位<a href="mailto:.@FieldResult">.@FieldResult</a>Ҏ(gu)的name()属性标识实体组件的属? column( ) 属性标识通过原生查询q回的结果集栏位.<br />在这个例子中,我们需要指定@FieldResults为客?原生查询为实体引用的每一个栏?因ؓ(f)我们只查询CreditCard 实体的ID和number?@FieldResultҎ(gu)需要被指定.?CreditCard的@EntityResultҎ(gu)?fields()属性定义CreditCard 属性每ơ查询的映射.因ؓ(f)Customer和CreditCard主键栏有相同的名?SQL查询需要L别出他们的不?cc.id As CC_IDq段SQL代码演示U标?<br />我们也可以用XML来表达:(x)<br /><entity-mappings><br /><sql-result-set-mapping name="customerAndCreditCardMapping"><br /><entity-result entity-class="com.titan.domain.Customer"/><br /><entity-result entity-class="com.titan.domain.CreditCard"/><br /><field-result name="id" column="CC_ID"/><br /><field-result name="number" column="number"/><br /></entity-result><br /></sql-result-set-mapping><br /></entity-mappings><br />9.3.3.2.混合标量和实体结?br />在我们的最l例?昄一个实体和一个标量值的混合.我们写一个原生查?来返回一个每ơE行由多少预定l成的E行列?<br />@SqlResultSetMapping(name="reservationCount",<br /><a href="mailto:entities=@EntityResult%28name=%22com.titan.domain.Cruise">entities=@EntityResult(name="com.titan.domain.Cruise</a>",<br /><a href="mailto:fields=@FieldResult%28name=%22id">fields=@FieldResult(name="id</a>", column="id")),<br /><a href="mailto:columns=@ColumnResult%28name=%22resCount">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>        FROM Cruise c LEFT JOIN Reservation ON c.id = Reservation.CRUISE_ID<br />GROUP BY c.id",<br />"reservationCount"); <br />}<br />reservationCount映射的定?原生查询表现对一个E航实体和一个所有E航预定的数目的请?a href="mailto:.@FieldResult">.@FieldResult</a>Ҏ(gu)标识c.id栏同Cruise实体相关?a href="mailto:.@ColumnResult">.@ColumnResult</a>Ҏ(gu)标识resCount栏同一个标量?<br />{h(hun)的XML文g:<br /><entity-mappings><br /><sql-result-set-mapping name="reservationCount"><br /><entity-result entity-class="com.titan.domain.Cruise"><br /><field-result name="id" column="id"/><br /></entity-result><br /><column-result name="resCount"/><br /></sql-result-set-mapping><br /></entity-mappings></p> <p>9.4命名查询<br />JAVA持久化提供了一U机?所以在建立一个查询时,你可以预先定义EJB QL或原SQL查询,q且引用它们通过名字.你可以先建立查询,然后建立JAVA语言中的Stringcd的常?在多U不同的情Ş中重复用他?你预先定义一个查?当在后面用到的时?可以很容易的q行调整<a href="mailto:.@javax.persistence.NamedQuery">.@javax.persistence.NamedQuery</a> Ҏ(gu)用在预定义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 Ҏ(gu)<a href="mailto:.@javax.persistence.QueryHint">.@javax.persistence.QueryHint</a>Ҏ(gu)定义厂商提供的暗C?q些暗示工作方式与Query.setHint( )Ҏ(gu)cM,它的描述在本单的前面.q是一个例:<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>    @NamedQuery(name="findFullyPaidCruises",<br />query=<br />"FROM Cruise cr<br />WHERE 0 < ALL (<br />SELECT res.amountPaid from cr.reservations res<br />)")<br />})<br />@Entity<br />public class Cruise {...}<br />在这个例子中定义了两个EJB QL查询在Cruise实体lgc?你可以引用这些定义在EntityManager.createNamedQuery( )Ҏ(gu)?<br />Query query = em.createNamedQuery("findFullyPaidCruises");<br />Query.setParameter("cruise", cruise);<br />{h(hun)于@NamedQuery的XML文g:<br /><entity-mappings><br /><named-query <br />name="getAverageReservation"><br /><query><br />SELECT AVG( r.amountPaid)<br />FROM Cruise As c JOIN c.reservations r<br />WHERE c = :cruise<br /></query><br /></named-query><br /></entity-mappings></p> <p>9.4.1.命名原生查询<br />@javax.persistence.NamedNativeQuery Ҏ(gu)用于预处理原生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.q两个属性是可选的,但是你必需臛_定义它们中的一?q是@NamedNativeQueryҎ(gu)的一个例?<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="mailto:entities=%7B@EntityResult%28entityClass=Customer.class">entities={@EntityResult(entityClass=Customer.class</a>)},<br /><a href="mailto:columns=%7B@ColumnResult%28name=%22CC_NUM">columns={@ColumnResult(name="CC_NUM</a>")}<br />)<br />@Entity<br />public class Customer {...}<br />你可以参考EntityManager.createNamedQuery( ) 的定?<br />Query query = em.createNamedQuery("findCustAndCCNum");<br />{h(hun)的XML文g:<br /><entity-mappings><br /><named-native-query name="findCustAndCCNum"<br />result-set-mapping="customerAndCCNumMapping"/><br /><query><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 /></query><br /></named-native-query><br /></entity-mappings></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="mailto:entities=%7B@EntityResult%28entityClass=Customer.class">entities={@EntityResult(entityClass=Customer.class</a>),<br />@EntityResult(entityClass=CreditCard.class,<br /><a href="mailto:fields=%7B@FieldResult%28name=%22id">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") q在相应属性加入@ColumnҎ(gu)<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 />强制cd转换<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.tkk7.com/jesson2005/aggbug/380882.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/jesson2005/" target="_blank">张金?/a> 2012-06-15 21:37 <a href="http://www.tkk7.com/jesson2005/articles/380882.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JPA EntityManager详解(?http://www.tkk7.com/jesson2005/articles/380881.html张金?/dc:creator>张金?/author>Fri, 15 Jun 2012 13:36:00 GMThttp://www.tkk7.com/jesson2005/articles/380881.htmlhttp://www.tkk7.com/jesson2005/comments/380881.htmlhttp://www.tkk7.com/jesson2005/articles/380881.html#Feedback0http://www.tkk7.com/jesson2005/comments/commentRss/380881.htmlhttp://www.tkk7.com/jesson2005/services/trackbacks/380881.htmlJPA EntityManager详解(?
★ 提示 ★

目前JBoss 4.2集成了的Tomcat版本?.5Q但Tomcat 6.0以后的版本中才支持用注释,所以如果将本例中Servletq行在JBoss 4.2中,q不能获得EntityManagerFactory对象Q但在符合J2EE 5.0的服务器中,q样q行是可以的?br />
虽然在目前JBoss 4.2版本中不支持使用注释Q但可以通过另一U方式来获得应用托管的EntityManager对象。代码如下所C?br />
1. public class TestServlet extends HttpServlet { 
2.  
3.     private EntityManagerFactory emf; 
4.  
5.     public TestServlet() { 
6.  
7.         super(); 
8.  
9.     } 
10.  
11.     public void doGet(HttpServletRequest request, HttpServletResponse response) 
12.  
13.             throws ServletException, IOException { 
14.  
15.         doPost(request, response); 
16.  
17.     } 
18.  
19.     public void doPost(HttpServletRequest request, HttpServletResponse response) 
20.  
21.             throws ServletException, IOException { 
22.  
23.         response.setContentType("text/html"); 
24.  
25.         PrintWriter out = response.getWriter(); 
26.  
27.         out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional //EN\">"); 
28.  
29.         out.println("<HTML>"); 
30.  
31.         out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>"); 
32.  
33.         out.println("  <BODY>"); 
34.  
35.         if (emf != null) { 
36.  
37.             /**创徏EntityManager 对象*/ 
38.  
39.             EntityManager entityManager = emf.createEntityManager(); 
40.  
41.             try { 
42.  
43.                 Query query = entityManager 
44.  
45.                         .createQuery("SELECT c FROM CustomerEO c"); 
46.  
47.                 List<CustomerEO> result = query.getResultList(); 
48.  
49.                 for (CustomerEO c : result) { 
50.  
51.                     System.out.println(c.getId() + "," + c.getName()); 
52.  
53.                 } 
54.  
55.             } finally { 
56.  
57.                 /**关闭EntityManager*/ 
58.  
59.                 entityManager.close(); 
60.  
61.             } 
62.  
63.         } 
64.  
65.         out.println("  </BODY>"); 
66.  
67.         out.println("</HTML>"); 
68.  
69.         out.flush(); 
70.  
71.         out.close(); 
72.  
73.     } 
74.  
75.     /**Servlet初始化时Q创建EntityManagerFactory 对象*/ 
76.  
77.     public void init() throws ServletException { 
78.  
79.         if (emf == null) { 
80.  
81.             emf = Persistence.createEntityManagerFactory("jpaUnit"); 
82.  
83.         } 
84.  
85.     } 
86.  
87.     /**Servlet销毁时Q关闭EntityManagerFactory对象*/ 
88.  
89.     public void destroy() { 
90.  
91.         if (emf.isOpen()) 
92.  
93.             emf.close(); 
94.  
95.     } 
96.  
97. } 

public class TestServlet extends HttpServlet {

private EntityManagerFactory emf;

public TestServlet() {

super();

}

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doPost(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional //EN\">");

out.println("<HTML>");

out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");

out.println("  <BODY>");

if (emf != null) {

/**创徏EntityManager 对象*/

EntityManager entityManager = emf.createEntityManager();

try {

Query query = entityManager

.createQuery("SELECT c FROM CustomerEO c");

List<CustomerEO> result = query.getResultList();

for (CustomerEO c : result) {

System.out.println(c.getId() + "," + c.getName());

}

} finally {

/**关闭EntityManager*/

entityManager.close();

}

}

out.println("  </BODY>");

out.println("</HTML>");

out.flush();

out.close();

}

/**Servlet初始化时Q创建EntityManagerFactory 对象*/

public void init() throws ServletException {

if (emf == null) {

emf = Persistence.createEntityManagerFactory("jpaUnit");

}

}

/**Servlet销毁时Q关闭EntityManagerFactory对象*/

public void destroy() {

if (emf.isOpen())

emf.close();

}

}



使用q种方式创徏EntityManagerFactory对象需要注意以下几个问题?br />
可以看到Q这里的EntityManagerFactory对象不是通过注入获得的,而是通过PersistencecM的静态方法createEntityManagerFactory来创建的?br />
— 正因为EntityManagerFactory对象是手动创建的Q所以在不再使用Ӟ一定要调用close()Ҏ(gu)手动关闭?br />
11.1.4.3  J2SE环境中获?br />
在J2SE环境中,获得应用托管的EntityManager对象只能通过手动创徏的方式,而不能用注释的方式Q与Web容器中不使用注释的方法相同,都是通过PersistencecMcreateEntityManagerFactory来创建的?br />
例如Q下面代码ؓ(f)J2SE环境中获得应用托EntityManager对象的方法?br />
1. public class CustomerClient { 
2.  
3.     public static void main(String[] args) { 
4.  
5.         /** 创徏EntityManagerFactory对象 */ 
6.  
7.         EntityManagerFactory emf = Persistence 
8.  
9.                 .createEntityManagerFactory("jpaUnit"); 
10.  
11.         /** 创徏entityManager对象 */ 
12.  
13.         EntityManager entityManager = emf.createEntityManager(); 
14.  
15.         Query query = entityManager.createQuery("SELECT c FROM CustomerEO c"); 
16.  
17.         List<CustomerEO> result = query.getResultList(); 
18.  
19.         for (CustomerEO c : result) { 
20.  
21.             System.out.println(c.getId() + "," + c.getName()); 
22.  
23.         } 
24.  
25.         /** 关闭entityManager对象 */ 
26.  
27.         entityManager.close(); 
28.  
29.         /** 关闭EntityManagerFactory对象 */ 
30.  
31.         emf.close(); 
32.  
33.     } 
34.  
35. } 

public class CustomerClient {

public static void main(String[] args) {

/** 创徏EntityManagerFactory对象 */

EntityManagerFactory emf = Persistence

.createEntityManagerFactory("jpaUnit");

/** 创徏entityManager对象 */

EntityManager entityManager = emf.createEntityManager();

Query query = entityManager.createQuery("SELECT c FROM CustomerEO c");

List<CustomerEO> result = query.getResultList();

for (CustomerEO c : result) {

System.out.println(c.getId() + "," + c.getName());

}

/** 关闭entityManager对象 */

entityManager.close();

/** 关闭EntityManagerFactory对象 */

emf.close();

}

}


但是Q在J2SE环境中用JPA需要将实现的JPA的第三方cd和数据库的驱动包Q设|到当前的运行环境下?br />
例如Q在Eclipse中创Z个Java目Q需要将JPA实现者的cdQ这里以HibernateZQ和MySQL的数据库q接包添加到构徏路径中,如图11-2所C?br />
11.1.5  ThreadLocal的?br />
对于在Web容器中用EntityManager对象Q这里需要做一些改q,才能更安全。读者应该了解,Servlet是非U程安全的,所以需要改变获得EntityManager对象的方式,q里W者徏议用ThreadLocalcR?br />
ThreadLocal是为每一个用某变量的线E都提供一个该变量值的副本Q每一个线E都可以独立地改变自q副本Q而不?x)和其他U程的副本冲H。从U程的角度看Q就好像每一个线E都完全拥有一个该变量Q这p决了Servlet非线E安全的问题?br />
首先~写一个EntityManagerHelperc,代码如下所C?br />
1. public class EntityManagerHelper { 
2.  
3.     
4.  
5.     private static final EntityManagerFactory emf; 
6.  
7.     private static final ThreadLocal<EntityManager> threadLocal; 
8.  
9.     
10.  
11.     /**初始?/ 
12.  
13.     static { 
14.  
15.         emf = Persistence.createEntityManagerFactory("jpaUnit");        
16.  
17.         threadLocal = new ThreadLocal<EntityManager>(); 
18.  
19.     } 
20.  
21.     
22.  
23.     /**通过threadLocal 获得EntityManager 对象*/ 
24.  
25.     public static EntityManager getEntityManager() { 
26.  
27.         EntityManager manager = threadLocal.get();      
28.  
29.         if (manager == null || !manager.isOpen()) { 
30.  
31.             manager = emf.createEntityManager(); 
32.  
33.             threadLocal.set(manager); 
34.  
35.         } 
36.  
37.         return manager; 
38.  
39.     } 
40.  
41.     
42.  
43.     /**关闭EntityManager 对象*/ 
44.  
45.     public static void closeEntityManager() { 
46.  
47.         EntityManager em = threadLocal.get(); 
48.  
49.         threadLocal.set(null); 
50.  
51.         if (em != null) em.close(); 
52.  
53.     } 
54.  
55.     
56.  
57.     public static void beginTransaction() { 
58.  
59.     getEntityManager().getTransaction().begin(); 
60.  
61.     } 
62.  
63.     
64.  
65.     public static void commit() { 
66.  
67.     getEntityManager().getTransaction().commit(); 
68.  
69.     }  
70.  
71.     
72.  
73.     public static Query createQuery(String query) { 
74.  
75.         return getEntityManager().createQuery(query); 
76.  
77.     } 
78.  
79.     
80.  
81. } 

public class EntityManagerHelper {



private static final EntityManagerFactory emf;

private static final ThreadLocal<EntityManager> threadLocal;



/**初始?/

static {

emf = Persistence.createEntityManagerFactory("jpaUnit");      

threadLocal = new ThreadLocal<EntityManager>();

}



/**通过threadLocal 获得EntityManager 对象*/

public static EntityManager getEntityManager() {

EntityManager manager = threadLocal.get();    

if (manager == null || !manager.isOpen()) {

manager = emf.createEntityManager();

threadLocal.set(manager);

}

return manager;

}



/**关闭EntityManager 对象*/

public static void closeEntityManager() {

EntityManager em = threadLocal.get();

threadLocal.set(null);

if (em != null) em.close();

}



public static void beginTransaction() {

getEntityManager().getTransaction().begin();

}



public static void commit() {

getEntityManager().getTransaction().commit();

}



public static Query createQuery(String query) {

return getEntityManager().createQuery(query);

}



}



q样l过改进后,在Servlet中创建EntityManager对象的方法修改ؓ(f)如下所C?br />
1. public class TestServlet extends HttpServlet { 
2.  
3.     public TestServlet() { 
4.  
5.         super(); 
6.  
7.     } 
8.  
9.     public void doPost(HttpServletRequest request, HttpServletResponse response) 
10.  
11.             throws ServletException, IOException { 
12.  
13.             EntityManager entityManager = EntityManagerHelper.getEntityManager(); 
14.  
15.             try { 
16.  
17.                 Query query = entityManager 
18.  
19.                         .createQuery("SELECT c FROM CustomerEO c"); 
20.  
21.                 List<CustomerEO> result = query.getResultList(); 
22.  
23.                 for (CustomerEO c : result) { 
24.  
25.                     System.out.println(c.getId() + "," + c.getName()); 
26.  
27.                 } 
28.  
29.             } finally { 
30.  
31.                 /**关闭EntityManager*/ 
32.  
33.                 EntityManagerHelper.closeEntityManager(); 
34.  
35.             } 
36.  
37.     } 
38.  
39. } 



]]>
JPA EntityManager详解(一)http://www.tkk7.com/jesson2005/articles/380880.html张金?/dc:creator>张金?/author>Fri, 15 Jun 2012 13:34:00 GMThttp://www.tkk7.com/jesson2005/articles/380880.htmlhttp://www.tkk7.com/jesson2005/comments/380880.htmlhttp://www.tkk7.com/jesson2005/articles/380880.html#Feedback0http://www.tkk7.com/jesson2005/comments/commentRss/380880.htmlhttp://www.tkk7.com/jesson2005/services/trackbacks/380880.htmlJPA EntityManager详解(一)
持久化上下文QPersistence ContextsQ的相关知识Q内容包括如何从Java EE容器中创建EntityManager对象、如何从Java SE中创建EntityManager对象、持久化上下文与事务QTransctionQ的关系Q以?qing)实体管理器工厂QEntity Manager FactoryQ的相关内容?
通过本章的学?fn),读者将深入掌握JPA中有x久化上下文、事务处理的相关知识Q从而能够更加深入地应用JPA?


11.1 获得EntityManager对象

那么如何获得EntityManager对象呢?q又是JPA中另外一个很重要的问题?


11.1.1  Java EE环境与J2SE环境

在详l讲qEntityManager对象之前Q读者首先要分清楚两个概念,即Java EE环境与J2SE环境。因为在本章后面的学?fn)中要经常提到这两个概念Q所以读者一定要先理解它们,Z后的学习(fn)打好基础?


— Java EE环境Q包括EJB容器和W(xu)eb容器?

Q?QWeb容器Q只q行W(xu)eb应用的容器,例如Tomcat是开源的Web容器Q它可以q行JSP、Servlet{?

Q?QEJB容器Q运行在EJBlg的容器,提供EJBlg的状态管理、事务管理、线E管理、远E数据资源访问、连接管理和安全性管理等pȝU服务。例如JBoss为EJB容器和W(xu)eb容器QWeb容器是集成了TomcatQ结合?

部v在EJB容器中的JAR包都可以认ؓ(f)是运行在EJB容器中。但JBoss中的Web应用Q比如war包中的类׃是运行在EJB容器中,而是q行在Web容器中?

— J2SE环境

最普通Javaq行环境Q例如一个HelloWorld的JavaE序是q行在J2SE的环境中Q通常使用main入口Ҏ(gu)作ؓ(f)E序启动的触发?

如图11-1所C,它说明了Java EE与J2SE环境的关pR?

11.1.2  两种cd的EntityManager对象

Ҏ(gu)EntityManager对象的管理方式,可以有以下两U类型?

— 容器托管的(container-managedQEntityManager对象

容器托管的EntityManager对象最单,E序员不需要考虑EntityManagerq接的释放,以及(qing)事务{复杂的问题Q所有这些都?l容器去理。容器托的EntityManager对象必须在EJB容器中运行,而不能在Web容器和J2SE的环境中q行。本书前面讲q的 EntityManager对象都是通过注入 @PersistenceContext注释来获得的Q其实,q种获得EntityManager对象的方式就是容器托的?

— 应用托管的(application-managedQEntityManager对象

应用托管的EntityManager对象Q程序员需要手动地控制它的释放和连接、手动地控制事务{。但q种获得应用托管?EntityManager对象的方式,不仅可以在EJB容器中应用,也可以 JPAqEJB容器Q而与M的Java环境集成Q比如说Web容器、J2SE环境{。所以从某种角度上来_(d)q种方式是JPA能够独立于EJB环境q?行的基础?

理想状态下Q最好是选用容器托管的EntityManager对象的方式,但在Ҏ(gu)的环境下Q还是需要用应用托的EntityManager对象q种方式?

正是因ؓ(f)应用托管的EntityManager对象的连接释放、事务控制比较复杂,所以在使用时涉?qing)的相关内容比较多,q些内容在本章后面部分详细讲述Q这里读者应对两U方式有一个大致的了解Q两UEntityManager对象cd的比较如?1-1所C?

?1-1  容器托管与应用托的EntityManager对象Ҏ(gu)

比较内容

容器托管的(container-managedQEntityManager对象

应用托管的(application-managedQEntityManager对象

获得方式

两种方式Q? @PersistenceContex注入 2 JNDI获得

EntityManagerFactory创徏

支持事务

JTA

JTA、RESOURCE_LOCAL

q行环境

EJB容器

EJB容器、Web容器、J2SE环境

11.1.3  容器托管的(container-managedQEntityManager对象

容器托管的EntityManager对象只能q行在EJB容器中。所以可以这L(fng)解,只有在EJB-JAR包中Q才可以获得容器托管的EntityManager对象Q否则只能获得应用托的EntityManager对象?

在EJB容器中获得EntityManager对象主要有两U方式,即@PersistenceContext注释注入和JNDI方式获得?

11.1.3.1  通过@PersistenceContext注释注入

q种方式获得EntityManager对象最为常用,例如下面代码所C?

  1. @Stateless  
  2.   
  3. public class CustomerService implements ICustomerService {  
  4.   
  5.     @PersistenceContext(unitName = "jpaUnit")  
  6.   
  7.     private EntityManager entityManager;  
  8.   
  9.     public List<CustomerEO> findAllCustomers() {  
  10.   
  11.         Query query = entityManager.createQuery("SELECT c FROM CustomerEO c");  
  12.   
  13.         List<CustomerEO> result = query.getResultList();  
  14.   
  15.         for (CustomerEO c : result) {  
  16.   
  17.             System.out.println(c.getId()+","+c.getName());  
  18.   
  19.         }  
  20.   
  21.         return result;  
  22.   
  23.     }  
  24.   
  25. }  


在用此U方式创建EntityManager对象Ӟ需要注意以下几个问题?

— @PersistenceContext注释中,其中unitName为persistence.xml文g?lt;persistence-unit>元素中的属?#8220;name”的|表示要初始化哪个持久化单元,如下所C?

Xml代码
  1. <persistence>  
  2.   
  3.     <persistence-unit name="jpaUnit" transaction-type="JTA">  
  4.   
  5.     </persistence-unit>  
  6.   
  7. </persistence>  


— @PersistenceContext注释中还可以配置其他的设|,它的定义如下所C?

Java代码
  1. @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME)  
  2.   
  3. public @interface PersistenceContext{  
  4.   
  5.     String name() default "";  
  6.   
  7.     String unitName() default "";  
  8.   
  9.     PersistenceContextType type default TRANSACTION;  
  10.   
  11.     PersistenceProperty[] properties() default {};  
  12.   
  13. }  


— 其中PersistenceContextType可以讄创徏EntityManager对象Ӟ持久化上下文的作用范_(d)它的意义在于Ҏ(gu)状态的BeanQStateless BeanQ可以跨事务操作实体。它主要有两U方式,定义如下所C?
Java代码
  1. public enum PersistenceContextType {  
  2.   
  3.     TRANSACTION,  
  4.   
  5.     EXTENDED  
  6.   
  7. }  


默认情况下用TRANSACTIONQ有关TRANSACTION方式和EXTENDED方式创徏EntityManager对象的异同,在下文中详l讲qͼq里读者简单了解一下即可?

11.1.3.2  通过JNDI的方式获?

如果指定了@PersistenceContext注释中的name|则设|了持久化上下文的JNDI名称。通过SessionContext可以创徏EntityManager对象?

例如Q下面代码ؓ(f)通过JNDI方式获得EntityManager对象?

  1. @Stateless  
  2.   
  3. @PersistenceContext(name="jpa")  
  4.   
  5. public class CustomerService implements ICustomerService {  
  6.   
  7.     @Resource  
  8.   
  9.     SessionContext ctx;  
  10.   
  11.     public List<CustomerEO> findAllCustomers() {  
  12.   
  13.         EntityManager entityManager = (EntityManager) ctx.lookup("jpa");  
  14.   
  15.         Query query = entityManager.createQuery("SELECT c FROM CustomerEO c");  
  16.   
  17.         List<CustomerEO> result = query.getResultList();  
  18.   
  19.         for (CustomerEO c : result) {  
  20.   
  21.             System.out.println(c.getId()+","+c.getName());  
  22.   
  23.         }  
  24.   
  25.         return result;  
  26.   
  27.     }  
  28.   
  29. }  


11.1.4  应用托管的(application-managedQEntityManager对象

应用托管的EntityManager对象Q不仅可以在Java EE环境中获得,也可以应用在J2SE的环境中。但无论是在什么情况下获得的EntityManager对象Q都是通过实体理器工?QEntityManagerFactoryQ对象创建的。所以如何获得应用托的EntityManager对象关键?EntityManagerFactory对象如何获得?

下面分别讲q在EJB容器、Web容器和J2SE环境中如何获得EntityManagerFactory对象?

11.1.4.1  EJB容器中获?

在EJB容器中,EntityManagerFactory对象可以通过使用注入@PersistenceUnit注释获得Q例如下面代码ؓ(f)在EJB容器中,获得应用托管的EntityManager对象的方法?

  1. @Stateless  
  2.   
  3. public class CustomerService implements ICustomerService {  
  4.   
  5.     @PersistenceUnit(unitName="jpaUnit")  
  6.   
  7.     private EntityManagerFactory emf;  
  8.   
  9.     public List<CustomerEO> findAllCustomers() {  
  10.   
  11.         /**创徏EntityManager对象*/  
  12.   
  13.         EntityManager em = emf.createEntityManager();  
  14.   
  15.         Query query = em.createQuery("SELECT c FROM CustomerEO c");  
  16.   
  17.         List<CustomerEO> result = query.getResultList();  
  18.   
  19.         for (CustomerEO c : result) {  
  20.   
  21.             System.out.println(c.getId()+","+c.getName());  
  22.   
  23.         }  
  24.   
  25.         /**关闭EntityManager */  
  26.   
  27.         em.close();  
  28.   
  29.         return result;  
  30.   
  31.     }  
  32.   
  33. }  

通过以上的EntityManager对象代码Q可以ȝZ下几个问题?

— 应用托管的EntityManager对象Q要在代码中手动地创建和关闭Q例如下面代码所C?

EntityManager em = emf.createEntityManager();

/**其他的业务逻辑*/

em.close();

q点正是与容器托的EntityManager对象的最大不同之处。事实上Q容器托的EntityManager对象Q它的创建和关闭是由容器负责理的,所以不需要编写代码来控制?

— 应用托管的EntityManager对象Q都是通EntityManagerFactory对象来创建的。在容器中可以通过使用注入@PersistenceUnit注释的方法实玎ͼ它的定义如下所C?

  1. @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME)  
  2.   
  3. public @interface PersistenceUnit{  
  4.   
  5.     String name() default "";  
  6.   
  7.     String unitName() default "";  
  8.   


其中Q属性unitName为persistence.xml文g?lt;persistence-unit>元素中的属?#8220;name”的|表示要初始化哪个持久化单元,与@PersistenceContext注释中unitName属性相同?

11.1.4.2  Web容器中获?

在Web容器中,EntityManagerFactory对象也可以通过使用注入@PersistenceUnit注释获得。例如,下面代码为在 Servlet中,获得应用托管的EntityManager对象的方法?/syntaxhighlighter/clipboard_new.swf">
  1. public class TestServlet extends HttpServlet {  
  2.   
  3.     @PersistenceUnit(unitName = "jpaUnit")  
  4.   
  5.     private EntityManagerFactory emf;  
  6.   
  7.     public TestServlet() {  
  8.   
  9.         super();  
  10.   
  11.     }  
  12.   
  13.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  14.   
  15.             throws ServletException, IOException {  
  16.   
  17.         doPost(request, response);  
  18.   
  19.     }  
  20.   
  21.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  22.   
  23.             throws ServletException, IOException {  
  24.   
  25.         response.setContentType("text/html");  
  26.   
  27.         PrintWriter out = response.getWriter();  
  28.   
  29.         out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional //EN\">");  
  30.   
  31.         out.println("<HTML>");  
  32.   
  33.         out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");  
  34.   
  35.         out.println("  <BODY>");  
  36.   
  37.         if (emf != null) {  
  38.   
  39.             /**创徏EntityManager 对象*/  
  40.   
  41.             EntityManager entityManager = emf.createEntityManager();  
  42.   
  43.             try {  
  44.   
  45.                 Query query = entityManager  
  46.   
  47.                         .createQuery("SELECT c FROM CustomerEO c");  
  48.   
  49.                 List<CustomerEO> result = query.getResultList();  
  50.   
  51.                 for (CustomerEO c : result) {  
  52.   
  53.                     System.out.println(c.getId() + "," + c.getName());  
  54.   
  55.                 }  
  56.   
  57.             } finally {  
  58.   
  59.                 /**关闭EntityManager*/  
  60.   
  61.                 entityManager.close();  
  62.   
  63.             }  
  64.   
  65.         }  
  66.   
  67.         out.println("  </BODY>");  
  68.   
  69.         out.println("</HTML>");  
  70.   
  71.         out.flush();  
  72.   
  73.         out.close();  
  74.   
  75.     }  
  76.   
  77. }  


]]>
վ֩ģ壺 պӰ߹ۿ| aëƬȫ߲**| ŮڵƵվ| ĻƷѾþ| ߹ۿƬ˳Ƶ| ѹҹ߹ۿ| պ߲ȫ| ѿmvվ| Ʒһ߹ۿ | ששר2023| ɫһ| йڵëƬѸ| ޵Ӱѹۿ| Ƭѹۿ| ޾ƷþþӰԺӰƬ | Ʒѹۿþþ| AVһþ| AV12þ| ձ| ߲91 | aëƬѲ| ޵һվ| þþþAVרվ | ƷһëƬ| 99þùƷһ | Ļȫ8 | ŷƵ| ŷ޾þav| ŷഺɫУ԰С˵| ţţ߾ƷƵۿ| ԻȫƵַ| aëƬav| Ƶ߹ۿַ| Ƶѹۿ| ɫַѴȫ| ۺС˵| Ʒ˿| 99ƷƵ߹ۿ| ѿŮˬƵ| AV12þ| պ߹ۿ|