歡迎您光臨本站 註冊首頁

編程基礎:JPA學習筆記(二)

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0

  /**

  持久化服務

  1.託管與非託管實體

  Persistener context是由一組受託管的實體對象實例所構成的集合,他受entity manager的管理.一旦persistent context被

  關閉,所有的實體對象都會脫離EntityManager而成為非託管對象.JPA中有兩種類型的persistent context,分別是

  i.transaction-scoped persistence

  他只能在事物範圍內存在著,他們會在事務結束后被關閉,transaction-scope persistent將被銷毀,託管實體對象實例也將處於

  只有受伺服器管理的persistent context才可以是事物範圍的,換言之,必須被註解@PersistentContext表示的EntityManager實

  列才可以是事務管理的.看代碼.

 


 */
  @persistenceContext(UnitName="EntityName")
  EntityManager entityManager;
  @TransactionAttribute(REQUIRED)
  public Customer someMethod(){
  Customer cust = entityManager.find(Customer.class,new Integer(1));
  cust.setName("new name");
  return cust;
  }
  /**

  由entityManager返回的Customer實例會在整個JTA事物內保持存在姿態,當JTA事務完成後,有setName調用引起的數據更改會被同步

  到資料庫中.entityManager對象將會被銷毀,改對象不在託管了.

  ii.Extented persistent context

  我們也可以將persistent context配置成超出事務的範圍,與Extented persistent context向關聯的對象會一直保持託管狀態,甚至

  在事務提交后也是如此,在某些場景下特別有用,你想保持資料庫連接,又不希望使用長事務,長事務會在佔用JDBC連接,這樣的數據

  寶貴資源.

  2.為persistent Unit打包

  每個EntityManager負責將一定數量的一組類映射到資料庫中,這組類就叫做persistent Unit.它是在persistent.xml文件中定義的,根據

  JPA標準的要求,改部署文件是必須的.一個persistent.xml可以定義一個或多個persistent unit.他被放在各類的文件的meta-inf目錄中.

  每個persistent unit只能關聯一個且僅一個數據源,在javaEE環境中,我們通過persistent.xml文件來配置,下面我們來分析下persistent

  .xml文件的格式.


<?xml version="1.0" encoding="GBK"?>
<persistence>
<persistence-unit name="" transaction-type="">
<description></description>
<provider></provider>
<class></class>
<mapping-file />
<jar-file />
<property name=""></property>
</persistence-unit>
</persistence>

  參看上面的代碼,name定義了unit的引用名,,提供注入用註解.該屬性是必須的.屬性transaction-type指明了你是希望persistent unit受JavaEE事務管理

  並與之集成,還是使用resource-local來管理.後者在JavaSE環境中使用.provider指定了實現javax.persistence.PersistenceProvider介面的類的全局

  限定名稱.property元素定義了一組廠商的專有屬性.建議使用class元素來定義需要映射到關係資料庫中的類.

  3.獲得EntityManager

  如果是在EJB環境中應用JPA,強烈建議使用@PersistenceContext註解或等價的XML描述.看代碼:

 


 */
  @Stateless
  public class MySessionBean implements MySessionRemote{
  @PersistenceContext(unitName="titan")
  private EntityManager entitymanager;
  ...
  }
  /**

  需要注意的是:默認情況下,在使用@PersistenceContext註解時,容器會將一個transaction-scoped類型的persistent context注入EJB.類型為Extended的Entity

  Manager只能注入到statefull session bean中.看代碼:


  */
  @Stateful
  public class MyStatefulBean implements MyStatefulRemote{
  @PersistenceContext(unitName="titan", type=PersistenceContextType.EXTENDED)
  private EntityManager entitymanager;
  ...
  }

  4.操作EntityManager

  i.持久化實體:就是將對象插入到資料庫中,你所持久化的還是未曾保持到資料庫中的實體,要持久化實體,要為實體分配內存,然後設置成員屬性,並設置好與其他

  對象可能存在的任何關聯關係,你就可以調用EntityManager.persist()方法來保持該實體了.


  */
  Customer cust = new Customer();
  cust.setName("Bill");
  entityManager.persist(cust);
  /**

  當調用persist()方法后,EntityManager會將Customer添加到等待資料庫插入的隊列中,對象實例即處於託管狀態,實際的操作要看:如果實在事務範圍內調用,插入操作

  可能馬上就執行,也可能在事務提交時執行,這依賴於flush模式,任何時候你都可以通過flush操作在一個事務內強制插入操作.

  ii.查找實體:提供了2種方法:find(),getReference().


*/
  public interface EntityManager{
   T find(Class entityClass, Object primayKey);
   T getReference(Class entityClass, Object primarykey);
  }
  /**

  2個方法都接受實體的class和代表實體主鍵的對象作為參數,區別是如果找不到指定實體時,find方法會返回null,getReference方法會拋出javax.persistent.EntityNotFound

  Exception,並且該方法並不保證實例的內部狀態不會被初始化.若是transaction-scope persistence contenxt,則返回遊離對象(記住是在事務範圍之外調用這2個方法).


  */
  Customer cust = entityManager.find(Customer.class,1);
  /**

  我們還可以使用EJB QL來查詢,使用CreateNativeQuery()來創建Query對象來進行查詢.


  */
  Query query = entityManager.CreateQuery("FROM Customer c WHERE id=2");
  Customer cust = (Customer)query.getSingleResult();
  /**

  由於你一旦調用了find(),getResource()方法,或使用查詢對象執行了一次查詢,所得的entity bean 在persisten測 context關閉前仍將處於託管狀態,在此期間,你可以像其他

  對象那樣隨便更改entity bean實例的狀態,任何更改都將自動過手動地同步到資料庫中.

  iii.合併實體:你可以使用EntityManager的meger()方法,將遊離實體的狀態合併到資料庫中,假設有一個Swing客戶端,它調用了TravleAgent Session bean的遠程方法,用以查找

  資料庫中的cabinet實體.看代碼:


  */
  @persistenceContext EntityManager entityManager;
  @TransactionAttribute(REQUIRED)
  public Cabin findCabin(int pid){
  return entityManager.find(Cabin.class, pid);
  }
  /**

  在findCabin()結束后,persistence context被銷毀,entity bean 處於非託管狀態,當Cabin實例被序列化,並被送到遠程的Swing客戶端,此時,該Cabin實例是一個普通的Java對象

  .Swing客戶端更改了這一Cabin實例的狀態,然後將其重新送回伺服器.看代碼:

 


 */
  Cabin cabin = trvalAgent.findCabin(1);
  cabin.setBedCount(4);
  trvalAgent.updateCabin(cabin);
  //--------------------------------------------//
  @persistenceContext EntityManager entityManager;
  @TransactionAttribute(REQUIRED)
  public void updateCabin(Cabin cabin){
  Cabin copy = entityManager.merge(cabin);
  }
  /**

  需要注意2中情況:

  1.若EntityManager未曾管理與傳入的cabin參數有著相同的Cabin實例,則merge()方法會創建該參數的一份完整拷貝做為方法的返回值,該拷貝受entityManager對象的管理,並且任何

  針對該份操作做的更改,而傳入的cabin參數仍將保持遊離狀態,不受託管.

  2.若擁有與傳入的Cabin參數有著相同的Cabin實例,則託管到託管的對象實例中,其餘的同上操作.

  本文出自 「stoneli88」 博客http://stoneli88.blog.51cto.com/333387/220543


[火星人 ] 編程基礎:JPA學習筆記(二)已經有1040次圍觀

http://coctec.com/docs/java/show-post-60816.html