轉自: http://blog.csdn.net/redmarketing/archive/2006/01/16/580440.aspx
Java EE5作為新一代Java企業開發平台的規範,從開始設計就引來了整個java開發社群的注目,引起無數的辯論和帶來了衆多的期盼。Java EE5作為J2EE平台誕生幾近6年後的第4代規範重點關注的是目前java開發的幾個熱點:開發效率,運作效率和企業應用整合。目标也是讓J2EE開發 簡單,簡單再簡單。那我們就看看J2EE5規範到底有什麼,是否真的能給開發者/企業帶來真正的實惠?
Java EE5規範是一個所謂的雨傘規範(Umbrella),在其下是一系列的子規範,主要包括:
EJB 3.0 (JSR 220) Java Persistence API 1.0 (JSR 220) JSP 2.1 (JSR 245) JSF 1.2 (JSR 252) JAX-WS 2.0 (JSR 224) StAX 1.0 (JSR 173) JAXB 2.0 (JSR 222) Web Services Annotations 1.0 (JSR 181) Common Annotations 1.0 (JSR 250) SAAJ 1.3 maintenance | JTA 1.1 maintenance JavaMail 1.4 & JAF 1.1 maintenance JSTL 1.2 maintenance Java EE Mgmt maintenance JACC maintenance Servlet maintenance Java EE Deployment maintenance WSEE maintenance |
Java Persistence API 1.0( EJB3 Entity Bean) 在Java EE5中, Entity Bean做為EJB規範中負責持久化的元件将逐漸成為一個曆史名詞了,作為J2EE 4規範中最為人所垢病的Entity Bean在Java EE5中被推到重來,取而代之的是java開發的通用持久化規範Java Persistence API 1.0, 其實就是完全重新定義了的Entity Bean規範(目前在很多場合中,由于曆史原因我們仍然使用ejb3持久化來稱呼這個規範)。JPA作為java中負責關系資料持久化的元件已經完全獨立 出來成為一個單獨的規範,而不再屬于Enterprise Java Bean的範疇(EJB更多的是指Stateless/Stateful session bean和Message Driven Bean)。
Java Persistence AP(JPA)可以說是java持久化技術的一個集大成者,它吸取了Hiberante,JDO,TopLink等優秀技術和架構,将這幾年發展成熟起來 的基于POJO模型的O/R Mapping技術标準化,成為在J2EE和J2SE環境中通用的java持久化API。值得注意的是Java Persistence API并不是J2EE環境專用,而是在java中的通用API。意味着我們可以在任何需要通路關系資料庫的地方使用JPA,甚至包括swing開發的桌面 應用。JPA也不要求一定在J2EE容器中才能運作,而是任何有JVM的環境都可以運用。 這就使得我們可以很容易的把JPA作為一個持久化元件自由地和各種容器/架構(EJB3容器, Spring等等)組合。
JPA如何簡化原來EJB2中Entity Bean的開發,看一個簡單對比:
EJB2.0 | EJB3.0(JPA) | |
Business Interface | 無需定義接口 | |
映射配置檔案 | 編寫EJB3 Deployment descriptor | 可選 |
EJB實作 |
在JPA 中,ejb3的Entity Bean就是一個簡單的java bean,即POJO( Plain Old Java Object)。不象EJB2中的EntityBean需要跟容器有密切的關聯(EJB2中必須有EntityContext),EJB3 中的entityBean和容器無關,事實上在JPA中,EntityBean也不再稱為EntityBean,而是Entity,和Session Bean/Message Driven Bean的仍然存在的EJB差別開來。
為了簡化O/R Mapping的配置,JPA大量采用JDK1.5的最重要的新特性annotaion直接在java代碼中進行配置的标注。 采用annotation标注O/R Mapping配置可以大幅度減少以往使用xml配置O/R Mapping工作量,提高效率和可維護性。
下面是一個最簡單的一對一關聯關系采用annotation和xml的配置比較。
Java Persistence API(EJB3 Persistence) | Hiberante | |
配置檔案 | 可選 | 需要 |
One-To-One配置 | 可選 | |
采用annotation的優勢在于:
- 減少了配置檔案的數量,特别是在實體(Entity)比較多的系統中,維護大量的O/R Mapping xml配置檔案是不少的工作量。
- 減少了配置需要标注的内容。由于annotation由java compiler來編譯解析,很多需要在xml配置中顯式聲明的内容不再需要(比如變量名稱,類型,集合中的對象類型等)。
- Annotation的編譯期檢查可以避免xml檔案中容易出現的配置文法錯誤,在IDE中及時發現和糾正。
- 無需在xml配置檔案和java代碼中切換,較少思維的跳躍,提高了開發效率。
- annotation被編譯到java bytecode中,省略了xml的解析過程,極大的提升應用的啟動速度和記憶體占用(特别是Entity多的情況)。
JPA在啟動上做了很多程度的簡化,使我們能夠很容易地在容器内(container)和J2SE環境中使用JPA。JPA擁有一個最基本的工廠類 EntityManagerFactory。通過調用這個工廠類的createEntityManager()方法獲得EntityManager。所有 對實體(Entity)的操作包括持久化,查詢,删除等等操作都都定義EntityManager上。
public interface EntityManager {
public void persist(Object entity);
public
T merge(T entity);
public void remove(Object entity);
public
T find(Class
entityClass, Object primaryKey);
public
T getReference(Class
entityClass, Object primaryKey);
public void flush();
public void setFlushMode(FlushModeType flushMode);
public FlushModeType getFlushMode();
public void lock(Object entity, LockModeType lockMode);
public void refresh(Object entity);
public void clear();
public boolean contains(Object entity);
public Query createQuery(String ejbqlString);
public Query createNamedQuery(String name);
public Query createNativeQuery(String sqlString);
public Query createNativeQuery(String sqlString, Class result-
Class);
public Query createNativeQuery(String sqlString, String result-
SetMapping);
public void close();
public boolean isOpen();
public EntityTransaction getTransaction();
}
那又如何獲得EntityManagerFactory呢?不管是在J2EE或者J2SE中,都需要通過一個persistence.xml配置檔案對EntityMangaerFactory進行配置。下面是一個最簡單的persistence.xml的範例。
<entity-manager>
<name>myEntityManager>/name>
<provider>com.redsoft.ejb3.PersistenceProviderImpl>/provider>
<class>com.redsoft.samples.HelloEntityBean>/class>
<properties>
<property name="ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
<property name="ConnectionURL" value="jdbc:mysql://localhost/EJB3Test"/>
<property name="ConnectionUserName" value="ejb3"/>
<property name="ConnectionPassword" value="ejb3"/>
>/properties>
</entity-manager>
name – 定了目前這個EntityMangaerFactory的名字,我們可以在一個persistence.xml中定義多個EntityManagerFactory。
Provider – 定了提供EntityManagerFactory的具體實作類。這個實作類由不同的持久化産品開發商提供。例子中采用的是國産紅工場的ejb3持久化實 現的 EntityManagerFactory實作類。如如果我們需要更換成其他廠商的産品,就需要更換具體的實作類。
class – 列出所有需要被JPA管理的實體類。為了保證在J2SE/J2EE中的通用性和可移植性,JPA要求這裡必須列出所有被JPA管理的實體類。
properties – 由持久化廠商自行定義的屬性。
如果使用JTA事務,也可以使用 <jta-data-source>myDataSource</ jta-data-source>來定義連接配接池。
在J2EE 容器環境中和J2SE環境中,都是通過讀取這個配置檔案來初始化EntityMangaerFactory。在J2EE容器環境下,ejb3容器負責讀取 persistence.xml并初始化EntityManagerFactory,并将EntityManagerFactory幫定到JDNI中,這 樣我們就可以通過通路JNDI獲得EntityManagerFactory, 進而獲得EntityManager。由于EJB3容器支援IOC模式,我們也可以通過IOC将EntityMangerFactory直接注射給需要的 使用JPA持久化的java類。通過IOC注射的方式獲得EntityManagerFactory或者EntityManager是更友善,合理和推薦 的方式。
而在J2SE環境中,我們可以通過标準的javax.persistence.Persistence類來獲得 EntityManagerFactory。Javax.persistence.Persistence會在目前classpath或者jar包的 META-INF/下搜尋并讀persistence.xml後初始化EntityManagerFactory。
下面是一個簡單的示例如何在J2SE環境中獲得EntityManagerFactory并獲得EntityManager,運用EntityManager持久化HelloWorldEntityBean.
事實上不管是在J2SE還是J2EE中我們都可以這樣通過javax.persistence.Persistence來初始化EntityManagerFactory。
在 上面HelloWorld的例子中我們需要顯式調用 javax.persistence.Persistence.createEntityManagerFactory, 并且顯式地開始事務和關閉事務。在今天大量使用IOC托管容器的時代,這樣的編碼已經顯得落後。
作為J2EE一個部分的JPA自然可以利用EJB3的IOC容器托管事務和注射資源,同樣的也可以使用開源IOC容器spring來托管事務和注射資源。紅工場也提供了一個開源的spring DAO擴充 http://sourceforge.net/projects/ejb3daosupport 是來支援JPA和Spring的結合。
下面是一個如何在Spring中托管事務和在DAO中注入EntityManager的配置範例:
文中的例子可以從紅工場首頁下載下傳 http://www.redsoftfactory.com/chinese/index.html