版權(quán)聲明:可以任意轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章原始出處和作者信息及本聲明
作者:
Juntao Yuan ;simmone
原文地址:
http://www.javaworld.com/javaworld/jw-09-2005/jw-0912-ejb.Html
中文地址:
http://www.matrix.org.cn/resource/article/43/43839_EJB_POJO.html
關(guān)鍵詞: EJB EnterPRise POJO
概述
在這個(gè)EJB 3.0學(xué)習(xí)系列中的第二部分,你將學(xué)到如何使用POJO開發(fā)數(shù)據(jù)模型,還有如何透明的將那些數(shù)據(jù)對(duì)象模型與關(guān)系型數(shù)據(jù)庫(kù)相互映射。使用EJB 3.0中注釋式的實(shí)體bean,開發(fā)數(shù)據(jù)庫(kù)驅(qū)動(dòng)的應(yīng)用就是小菜一碟。
請(qǐng)閱讀有關(guān)EJB 3.0的整個(gè)學(xué)習(xí)系列:
第一部分:使用注釋開發(fā)POJO服務(wù)
第二部分:帶來(lái)簡(jiǎn)便的的持久化技術(shù)
(2000字;2005年9月12日)
在第一部分中,我討論了在企業(yè)級(jí)JavaBean 3.0(EJB)中注釋驅(qū)動(dòng)的POJO編程模型。我闡述了如何開發(fā)POJO服務(wù),如何讓容器服務(wù)使用POJO, 如何使用依賴注入來(lái)組合應(yīng)用。這些POJO服務(wù)主要是用來(lái)封裝應(yīng)用的商業(yè)邏輯。在商業(yè)邏輯的背后,現(xiàn)今的大多數(shù)應(yīng)用都有由一個(gè)高性能的關(guān)系型數(shù)據(jù)庫(kù)作為支撐的數(shù)據(jù)模型層。
在第二部分中,我將討論EJB 3.0實(shí)體bean如何利用POJO和注釋的優(yōu)勢(shì)來(lái)極大地簡(jiǎn)化你的數(shù)據(jù)模型以及它們與后臺(tái)關(guān)系數(shù)據(jù)庫(kù)的持久化。在我們進(jìn)入EJB 3.0實(shí)體bean的細(xì)節(jié)之前,讓我們先來(lái)看一下為什么對(duì)于企業(yè)級(jí)Java應(yīng)用,數(shù)據(jù)模型和持久化是如此巨大的一個(gè)挑戰(zhàn)。
對(duì)象-關(guān)系映射(ORM)
在Java虛擬機(jī)中,所有的數(shù)據(jù)都被模型化并且封裝在了類和對(duì)象的樹結(jié)構(gòu)中。但是在后端的關(guān)系型數(shù)據(jù)庫(kù)中,數(shù)據(jù)被模型化為關(guān)系型表,它們通過(guò)共享的鍵域(外鍵)相互關(guān)聯(lián)起來(lái)。相同的數(shù)據(jù)卻有兩個(gè)視圖,這對(duì)企業(yè)級(jí)Java的開發(fā)者來(lái)說(shuō)是一個(gè)艱難的挑戰(zhàn):當(dāng)你想從持久化的數(shù)據(jù)存儲(chǔ)中存取數(shù)據(jù)時(shí),你必須在對(duì)象與關(guān)系表達(dá)之間來(lái)回轉(zhuǎn)換,這一過(guò)程叫做對(duì)象-關(guān)系映射(ORM)。在Java EE(Java企業(yè)版,以前叫做J2EE),你可以通過(guò)兩個(gè)途徑來(lái)實(shí)現(xiàn)對(duì)象-關(guān)系映射。
手動(dòng)的:你可以使用Java數(shù)據(jù)庫(kù)連接來(lái)直接操作持久化-對(duì)于簡(jiǎn)單應(yīng)用的直截了當(dāng)?shù)慕鉀Q方案。JDBC API的類是緊貼在關(guān)系型數(shù)據(jù)庫(kù)表、行和列之后的數(shù)據(jù)模型。你必須手動(dòng)地在應(yīng)用的內(nèi)部對(duì)象模型與JDBC對(duì)象模型之間進(jìn)行轉(zhuǎn)換,如果你的應(yīng)用的內(nèi)部模型本身就類似于2維的關(guān)系表的話,那采用JDBC是最佳手段。
自動(dòng)的:你可以把ORM交給框架。框架通常向你提供一個(gè)可以和任意數(shù)據(jù)對(duì)象進(jìn)行交互的API。通過(guò)那個(gè)API,你可以存儲(chǔ)、獲取和查詢數(shù)據(jù)庫(kù)。框架在后臺(tái)完成了框架對(duì)象的轉(zhuǎn)換。因?yàn)樘囟ǖ年P(guān)系型SQL查詢不適合對(duì)象接口,ORM框架通常定義它自己的查詢語(yǔ)言,并且自動(dòng)為當(dāng)前關(guān)系型數(shù)據(jù)庫(kù)生成正確的SQL語(yǔ)句。對(duì)于擁有復(fù)雜的數(shù)據(jù)模型的應(yīng)用來(lái)說(shuō),基于框架的手段能為你節(jié)省很多時(shí)間并降低了出錯(cuò)的可能。
對(duì)象數(shù)據(jù)庫(kù)
一個(gè)對(duì)象型數(shù)據(jù)庫(kù)直接在數(shù)據(jù)庫(kù)中存儲(chǔ)、獲取和查找對(duì)象。因?yàn)椴辉傩枰狾RM,所以它對(duì)于Java應(yīng)用非常適合。不幸的是,現(xiàn)今的對(duì)象型數(shù)據(jù)庫(kù)相對(duì)于關(guān)系型數(shù)據(jù)庫(kù)來(lái)說(shuō)還不成熟,速度也慢。你可以這樣說(shuō),一個(gè)好的ORM框架從根本上來(lái)說(shuō),就是為關(guān)系型數(shù)據(jù)庫(kù)提供一個(gè)對(duì)象型數(shù)據(jù)庫(kù)的接口。兩者它都要做到最好。
這篇文章,我將重點(diǎn)放在專為企業(yè)級(jí)Java ORM應(yīng)用設(shè)計(jì)的自動(dòng)框架上。下一節(jié),我將提到幾個(gè)流行的ORM框架和EJB 3.0中幾個(gè)關(guān)鍵的革新。
ORM 框架
EJB 實(shí)體bean是Java EE中“官方”的ORM解決方案。但是,在EJB1.x和2.x中,實(shí)體bean的難以使用是出了名的,原因如下:
●EJB 1.x和2.x實(shí)體bean必須遵守一種嚴(yán)格的組件模型。每一個(gè)bean類必須實(shí)現(xiàn)一個(gè)home接口和一個(gè)商業(yè)接口。它們必須從某種抽象類中繼承,而且必須實(shí)現(xiàn)其所有方法,即使它們多數(shù)為空。這樣的一種嚴(yán)格組件模型使得想從EJB 1.x和2.x的實(shí)體bean中構(gòu)建面向?qū)ο蟮臄?shù)據(jù)模型幾乎變得不可能了。
●EJB 1.x和2.x容器需要特別冗長(zhǎng)的xml配置文件來(lái)建立實(shí)體bean與關(guān)系型數(shù)據(jù)庫(kù)中的表映射。那些文件是非常單調(diào)乏味和容易出錯(cuò)的。
簡(jiǎn)而言之,EJB 1.x和2.x實(shí)體bean是一個(gè)設(shè)計(jì)拙劣的ORM框架。它既沒(méi)有滿足Java數(shù)據(jù)對(duì)象模型的需求,也沒(méi)有滿足關(guān)系表數(shù)據(jù)模型的需求。出于對(duì)EJB 1.x和2.x實(shí)體bean的不滿,開發(fā)者開始尋找其它的ORM方案。實(shí)際使用中,開源的Hibernate(JBoss開發(fā))和Oracle公司的TopLink是最成功的兩個(gè)POJO ORM框架。Hibernate和TopLink都是基于POJO的。它們不依賴于任何預(yù)定義的組件模型。作為替代,它們使用POJO數(shù)據(jù)對(duì)象(簡(jiǎn)單的JavaBean式的),自動(dòng)地解讀出如何映射它們,以及它們之間的關(guān)系(關(guān)系型數(shù)據(jù)庫(kù))。通常,JavaBean類映射到一張數(shù)據(jù)庫(kù)表,并根據(jù)數(shù)據(jù)庫(kù)表中的外鍵映射出類之間的關(guān)系。你可以在一個(gè)簡(jiǎn)單直接的xml配置文件中指明ORM的配置信息,比如JavaBean類對(duì)應(yīng)的表名和屬性對(duì)應(yīng)的列名。你可以通過(guò)框架中的工具(如:Hibernate中的session類)來(lái)對(duì)那些POJO進(jìn)行操作(如:存儲(chǔ)、獲取和查找)。
EJB 3.0是建立在Hibernate和TopLink的思想和成功之上。它為Java EE提供了一個(gè)標(biāo)準(zhǔn)的POJO ORM框架。另外,EJB 3.0有兩個(gè)超越現(xiàn)今所有持久化解決方案的關(guān)鍵革新:
●沒(méi)有使用XML文件來(lái)指明ORM配置信息, EJB 3.0允許開發(fā)者直接在POJO代碼中注釋出映射信息。舉例來(lái)說(shuō),你可以用注釋來(lái)指明每個(gè)JavaBean屬性對(duì)應(yīng)的關(guān)系型表列。在這篇文章的后面,你將看到更多的例子。注釋使得映射更直接,更容易維護(hù)了。
●EJB 3.0為實(shí)體bean定義了一個(gè)新的歸檔格式。每個(gè)檔案使用一組獨(dú)立的,為后端數(shù)據(jù)庫(kù)和ORM行為所專用的配置集來(lái)定義一個(gè)持久化上下文。在這篇文章的后面,我會(huì)討論持久化上下文。
現(xiàn)在,讓我們通過(guò)幾個(gè)簡(jiǎn)單的例子來(lái)看一下EJB 3.0是如何完成POJO ORM的。
映射一個(gè)簡(jiǎn)單的對(duì)象
在EJB 3.0中,每個(gè)實(shí)體bean都是一個(gè)簡(jiǎn)單的JavaBean式的類。為了告訴EJB 3.0容器這個(gè)類應(yīng)該為持久化進(jìn)行映射,你應(yīng)該用@Entity來(lái)注釋這個(gè)類。
每一個(gè)實(shí)體bean類映射到一個(gè)關(guān)系型數(shù)據(jù)庫(kù)表。默認(rèn)地,表名對(duì)應(yīng)類名。你可以用@Table來(lái)為類指定另一個(gè)表。每一個(gè)JavaBean屬性映射到表的列上,同樣的,默認(rèn)列名就是屬性名。你可以用@Column注釋在屬性的Setter方法上來(lái)改變這種默認(rèn)關(guān)系。下面是一個(gè)EJB 3.0的簡(jiǎn)單例子:
@Entity
// @Table (name="AlternativeTableName")
public class Person implements Serializable {
  
  protected int id;
  protected String name;
  protected Date dateOfBirth;
  
  public void setId (int id) {
    this.id = id;
  }
  
  @Id(generate = GeneratorType.AUTO)
  public int getId () {
    return id;
  }
  
  public void setName (String name) {
    this.name = name;
  }
  
  // @Column (name="AlternativeColumnName")
  public String getName () {
    return name;
  }
  
  public void setDateOfBirth (Date dateOfBirth) {
    this.dateOfBirth = dateOfBirth;
  }
  
  public Date getDateOfBirth () {
    return dateOfBirth;
  }
}
當(dāng)容器把Person類映射到Person SQL數(shù)據(jù)庫(kù)表以后,每一個(gè)Person實(shí)例就是表中的一條數(shù)據(jù)記錄。
映射一個(gè)簡(jiǎn)單的JavaBean類是容易的。但自動(dòng)ORM框架真正閃光之處在于映射互相關(guān)聯(lián)的對(duì)象。下一節(jié)中,我們看一下EJB 3.0如何操作對(duì)象間的關(guān)系。
關(guān)系
在一個(gè)數(shù)據(jù)模型里面,一般來(lái)說(shuō)類相互之間都會(huì)有某種聯(lián)系。比如,一個(gè)Person(個(gè)人)對(duì)象可以和一個(gè)Resume(確認(rèn))對(duì)象相關(guān)聯(lián),反過(guò)來(lái)也一樣(一對(duì)一關(guān)系);一個(gè)Person對(duì)象可以和多個(gè)CreditCard(信用卡)對(duì)象相關(guān),而一個(gè)CreditCard對(duì)象只能和一個(gè)Person對(duì)象相關(guān)(一對(duì)多關(guān)系)。多個(gè)Person對(duì)象可以和一個(gè)Address(地址)對(duì)象相關(guān),而一個(gè)Person對(duì)象只能對(duì)應(yīng)一個(gè)Address對(duì)象(多對(duì)一關(guān)系)。(譯者注:此處原著筆誤, Person與Address位置顛倒了;編者注:我看兩者是多對(duì)多的關(guān)系。一家人住在同一個(gè)地方,這個(gè)地址對(duì)于這一家人來(lái)說(shuō)是一對(duì)多的關(guān)系;房主在別的地方又買了一套房,房主與地址的關(guān)系是一對(duì)多的關(guān)系。)
在一個(gè)數(shù)據(jù)模型中,對(duì)象指針用來(lái)操作那些關(guān)系。舉例來(lái)說(shuō),一個(gè)Person對(duì)象可以有一個(gè)屬性(也就是域)指向一個(gè)Resume對(duì)象。而另一個(gè)屬性是CreditCard對(duì)象的集合。為了告知EJB 3.0容器對(duì)象間的關(guān)系,你只需簡(jiǎn)單地在POJO中注釋JavaBean屬性。
@Entity
public class Person implements Serializable {
  // ... ...
  protected Resume resume;
  protected CreditCard [] cards;
  protected Address addr;
  
  // ... ...
    
  @OneToOne
  public Resume getResume () {
    return resume;
  }
  
  // ... ...
  
  @ManyToOne
  // @JoinColumn (name="MyCustomId")
  public Address getAddr () {
    return addr;
  }
  
  // ... ...
  
  @OneToMany
  public Collection <CreditCard> getCards () {
    return cards;
  }
}
在關(guān)系型數(shù)據(jù)庫(kù)中,那些關(guān)系自動(dòng)地被EJB 3.0容器使用外鍵來(lái)重建了。舉例來(lái)說(shuō),Person表有一個(gè)外鍵包含了Resume表中相應(yīng)的主鍵。運(yùn)行時(shí),EJB 3.0容器加強(qiáng)了一對(duì)一的關(guān)系:它保證了Resume鍵值對(duì)于Person表中的每一行是唯一的。為了啟用Resume表到Person表的雙向查詢,你可以Resume表中定義一個(gè)Person屬性,并把它也加上@OneToOne注釋。
Person表中也有一個(gè)外鍵包含了Address表中相應(yīng)行的主鍵。這種情況下,相同的Address主鍵可以出現(xiàn)在多個(gè)Person行中,這是多對(duì)一關(guān)系。對(duì)于一對(duì)多的關(guān)系,映射稍有一點(diǎn)復(fù)雜,因?yàn)橥怄I列是定義在多對(duì)一表中的。于是,在CreditCard類中,你必須用@ManyToOne來(lái)定義一個(gè)Person屬性。
            改變外部鍵字段名
ORM中使用的外部鍵字段的名字是由容器自動(dòng)決定的或者由@JoinColumn注釋來(lái)顯式的指定。
上面討論的關(guān)系只是實(shí)體bean之間關(guān)系的一種類型,實(shí)體類之間另外一種重要關(guān)系是繼承。
繼承
面向?qū)ο笤O(shè)計(jì)方法的一個(gè)關(guān)鍵概念是繼承。使用繼承,你可以創(chuàng)建一個(gè)復(fù)雜的對(duì)象樹而不需要重復(fù)的代碼。舉例來(lái)說(shuō),Consultant(顧問(wèn))是提供有償服務(wù)的一個(gè)人,那么在我們的數(shù)據(jù)模型中,Consultant類就從Person(個(gè)人)類中繼承,并增加了一個(gè)價(jià)格屬性。不幸的是,當(dāng)今的關(guān)系型數(shù)據(jù)庫(kù)并不存在繼承的概念。ORM框架主要通過(guò)以下兩個(gè)手段來(lái)模仿這種行為:
●框架可以為每一個(gè)類生成一個(gè)單獨(dú)的表。子類的表重復(fù)了那些從父類的字段。子類和父類都存儲(chǔ)為各自對(duì)應(yīng)的表。
●框架可以使用包含了所有子類屬性的表。兩種類(父類和子類)的實(shí)例都存儲(chǔ)于同一張表—父類中不存在的字段(也就是,子類的字段)取null值。為了使繼承映射更為強(qiáng)壯,表也可以有一個(gè)“區(qū)別”列,它存儲(chǔ)的標(biāo)記表明該行數(shù)據(jù)映射到哪一個(gè)類。
EJB 3.0實(shí)體bean支持上述兩種映射策略,默認(rèn)是單表映射策略。你可以簡(jiǎn)單地用注釋指明子類的繼承策略和區(qū)別字段的名字。下面是Consultant類的例子,它從Person類中繼承:
@Entity
@Inheritance(discriminatorValue="C")
@DiscriminatorColumn(name="person_type")
public class Consultant extends Person {
  protected double rate;
  
  public void setRate (double rate) {
    this.rate = rate;
  }
  
  public double getRate () {
    return rate;
  }
}
從上面的例子中,容器使用默認(rèn)策略將Consultant類映射到Person類對(duì)應(yīng)的同一張表中。如果表中的person_type字段的值為C,那么那一行數(shù)據(jù)就代表了一個(gè)顧問(wèn)類。否則,當(dāng)前行代表的是一個(gè)普通的Person類。
持久化檔案
現(xiàn)在你的數(shù)據(jù)模型有了一組使用了注釋EJB 3.0實(shí)體bean的類,你可以將它們捆綁在一起布署到服務(wù)器環(huán)境中。EJB 3.0為實(shí)體bean定義了一種特殊的歸檔格式,叫做持久化檔案(文件后綴名為.par)。
一個(gè).par文件是一組實(shí)體bean類文件加上一個(gè)簡(jiǎn)單的配置文件META-INF/persistence.xml的jar打包文件。persistence.xml文件定義了持久化上下文,它告知EJB 3.0哪一個(gè)后端數(shù)據(jù)庫(kù)(數(shù)據(jù)源)與這一組實(shí)體bean相對(duì)應(yīng)。persistence.xml也包含了配置屬性的細(xì)節(jié)。舉例來(lái)說(shuō),JBoss EJB 3.0是在Hibernate 3.0之上實(shí)現(xiàn)的,于是你可以通過(guò)persistence.xml傳遞任意的Hibernate配置選項(xiàng)。這有一個(gè)范例persistence.xml文件,它包含了JBoss和Hibernate專用的配置屬性,包括SQL 方言(dialect)和二級(jí)緩存。
<entity-manager>
  <name>cal</name>
  <jta-data-source>java:/DefaultDS</jta-data-source>
  <properties>
    <property name="hibernate.dialect"  
            value="org.hibernate.dialect.MySQLDialect" />
    <property name="hibernate.cache.provider_class"
            value="org.jboss.ejb3.entity.TreeCacheProviderHook"/>
    <property name="hibernate.treecache.mbean.object_name"
            value="jboss.cache:service=EJB3EntityTreeCache"/>
  </properties>
</entity-manager>
實(shí)體管理器
一旦你部署了實(shí)體bean, 你必須通過(guò)EJB 3.0的實(shí)體管理器的API來(lái)訪問(wèn)和操作它們。EJB 3.0容器為每個(gè)部署的持久化上下文(也就是,.par文件)提供了一個(gè)實(shí)體管理器對(duì)象。從一個(gè)EJB 3.0 session bean POJO(參看第一部分)中 ,你可以通過(guò)@PersistenceContext注釋將實(shí)體管理器對(duì)象注入,并傳入上下文的名字。
@Stateless
public class ManagerBean implements Manager {
  @PersistenceContext (unitName="cal")
  protected EntityManager em;
  
  // Use "em" 
// 使用“em”
  // ... ...
}
基本操作
要?jiǎng)?chuàng)建一個(gè)數(shù)據(jù)對(duì)象并把它存入數(shù)據(jù)庫(kù)中,你只需簡(jiǎn)單地使用Java的new關(guān)鍵字來(lái)創(chuàng)建POJO,并把它傳給EntityManager.persist()方法。
Person p = new Person ();
p.setName ("A new baby");
p.setDateOfBirth (new Date ());
em.persist (p);
要從數(shù)據(jù)庫(kù)中取得對(duì)象,你可以使用EJB 3.0查詢語(yǔ)言來(lái)搜索數(shù)據(jù)庫(kù)。下面的例子演示了如何將Person表中的所有行作為Person Java對(duì)象的集合來(lái)返回。
// 得到所有人的對(duì)象
Collection <Person> persons = (Collection <Person>) 
    em.createQuery("from Person p").getResultList();
可管理的pojo
通過(guò)實(shí)體管理器保存和獲取的對(duì)象是被管理在持久化上下文中的。這意味著如果對(duì)象后來(lái)被改變了,那這種改變將會(huì)被自動(dòng)檢測(cè)并持久化到數(shù)據(jù)庫(kù)中。在下面的例子中,我們更新了一個(gè)可管理的POJO的一個(gè)屬性。這個(gè)改變會(huì)被EJB 3.0容 器自動(dòng)檢測(cè)到并發(fā)送給了數(shù)據(jù)。
Person p = em.find(Person.class, personId);
p.setName ("Another Name");
//p會(huì)在當(dāng)前事務(wù)結(jié)束時(shí)被自動(dòng)地更新到數(shù)據(jù)庫(kù)中去。
// 并沒(méi)用更多的API調(diào)用
既然EJB 3.0實(shí)體僅只是POJO,那么它們就可以能夠被序列化并通過(guò)網(wǎng)絡(luò)傳遞。如果一個(gè)對(duì)象不是被容器創(chuàng)建的(也就是說(shuō),它是從網(wǎng)絡(luò)連接中傳遞過(guò)來(lái)的或者是某一個(gè)遠(yuǎn)程調(diào)用返回的結(jié)果),那么持久化上下文并不會(huì)管理它。不過(guò),你可以通過(guò)調(diào)用EntityManager.merge()方法將一個(gè)非管理的POJO合并到持久化上下文中。下面是將一個(gè)解序列化的POJO合并入當(dāng)前持久化上下文中的例子。
InputStream in; 
// 初始化輸入流
Person p = Util.deserialize (in);
// ... ...
em.merge (p);
// p現(xiàn)在是一個(gè)可管理的對(duì)象了。p的任何改變將會(huì)被自動(dòng)檢測(cè)并持久化
p.setName ("Another Name");
數(shù)據(jù)庫(kù)同步
當(dāng)實(shí)體管理器對(duì)象在一個(gè)session bean中使用時(shí),它是和服務(wù)器的事務(wù)上下文綁定的。實(shí)體管理器在服務(wù)器的事務(wù)提交時(shí)提交并且同步它的內(nèi)容。在一個(gè)session bean中,服務(wù)器的事務(wù)默認(rèn)地會(huì)在調(diào)用堆棧的最后提交。當(dāng)然,你也可以通過(guò)注釋來(lái)為每個(gè)商務(wù)方法指定具體的事務(wù)屬性。下面的例子展示了如何為一個(gè)session bean的方法聲明一個(gè)新的事務(wù)。
@TransactionAttribute(TransactionAttributeType.REQUIRESNEW)
public void update () {
// 這個(gè)方法更新Person對(duì)象
// 更新將會(huì)在這個(gè)方法的末尾被提交和刷新到數(shù)據(jù)庫(kù)中
            批處理中刷新數(shù)據(jù)庫(kù)操作
為了只在當(dāng)事務(wù)提交時(shí)才將改變更新到數(shù)據(jù)庫(kù)中,容器將所有數(shù)據(jù)庫(kù)操作集中到一個(gè)批處理中,這樣就減少了代價(jià)昂貴的與數(shù)據(jù)庫(kù)的交互。
如果你需要在事務(wù)提交之前將更新刷新到數(shù)據(jù)庫(kù)中,你可以直接地調(diào)用EntityManager.flush()方法。或者你可以將一個(gè)方法注釋為@FlushMode(FlushModeType.NEVER),于是事務(wù)管理器將不會(huì)在方法的結(jié)尾(也就是事務(wù)的結(jié)尾)處刷新更新到數(shù)據(jù)庫(kù)中。這種情況下,你可以手工地來(lái)刷新數(shù)據(jù)庫(kù)以獲得對(duì)數(shù)據(jù)庫(kù)操作的最大控制。
總結(jié)
EJB 3.0 提供了一種簡(jiǎn)單有效的框架將Java POJO映射到SQL數(shù)據(jù)庫(kù)中的關(guān)系型表中。它基于Java類中的名字和結(jié)構(gòu)進(jìn)行智能的默認(rèn)映射策略。但你也可以用一組簡(jiǎn)單的注釋重載所有的默認(rèn)值,來(lái)處理復(fù)雜的對(duì)象關(guān)系。
EJB 3.0實(shí)體管理器提供了簡(jiǎn)單的API來(lái)持久化和從數(shù)據(jù)庫(kù)中查找對(duì)象。每一個(gè)實(shí)體管理器對(duì)象與一組映射的POJO相關(guān)聯(lián),并有著它自己的數(shù)據(jù)庫(kù)設(shè)置。它會(huì)自動(dòng)地捆綁到服務(wù)器的事務(wù)管理器中。
相關(guān)資源
這一系列的第一部分介紹了EJB 3.0的session bean和其它基于POJO的服務(wù)對(duì)象:“使用EJB 3.0簡(jiǎn)化企業(yè)級(jí)Java開發(fā),第一部分 使用注釋 開發(fā)POJO服務(wù)” 邁克爾.袁俊濤(JavaWorld, 2005年8月)
http://www.javaworld.com/javaworld/jw-08-2005/jw-0815-ejb3.html 
這篇文章所使用的代碼范例源于JBoss EJB 3.0的TrailBlazer應(yīng)用的代碼。你可以在線研究或從以下地址下載TrailBlazer:http://www.jboss.com/docs/trailblazer
“EJB 3.0的簡(jiǎn)易性”Raghu R.Kodali(Java 開發(fā)者雜志, 2005年8月)
下面是與這篇文章中所涉及內(nèi)容相關(guān)的學(xué)習(xí)資源列表:
o無(wú)狀態(tài) session beans: 
http://trailblazer.demo.jboss.com/EJB3Trail/serviceobjects/slsb/index.html 
o有狀態(tài) session beans: 
http://trailblazer.demo.jboss.com/EJB3Trail/serviceobjects/sfsb/index.html 
oSession bean 生命周期內(nèi)的回調(diào): 
http://trailblazer.demo.jboss.com/EJB3Trail/serviceobjects/lifecycle/index.html 
o消息驅(qū)動(dòng) beans: 
http://trailblazer.demo.jboss.com/EJB3Trail/serviceobjects/mdb/index.html 
oJBoss消息驅(qū)動(dòng) POJOs: 
http://trailblazer.demo.jboss.com/EJB3Trail/serviceobjects/mdpojo/index.html 
o針對(duì)服務(wù)端對(duì)象的依賴注入: 
http://trailblazer.demo.jboss.com/EJB3Trail/serviceobjects/injection/index.html 
o事務(wù)服務(wù): 
http://trailblazer.demo.jboss.com/EJB3Trail/services/transaction/index.html 
o安全服務(wù): 
http://trailblazer.demo.jboss.com/EJB3Trail/services/security/index.html 
o攔截器: 
http://trailblazer.demo.jboss.com/EJB3Trail/services/interceptor/index.html
●這些范例可以在JBoss 應(yīng)用服務(wù)器的4.0.3版本中運(yùn)行。請(qǐng)確認(rèn)下載和安裝步驟是否正確: 
http://trailblazer.demo.jboss.com/EJB3Trail/background/install/index.html
●邁克爾.袁早些時(shí)候在JavaWorld上發(fā)表的文章 “簡(jiǎn)化之路”(2005年2月)闡述了POJO編程模型對(duì)比老的EJB 2.1的優(yōu)勢(shì):
http://www.javaworld.com/javaworld/jw-02-2005/jw-0221-jboss4.html
●Anil Sharma所寫的“EJB 3.0技術(shù)手冊(cè)”(JavaWorld,2004年8月)是一個(gè)對(duì)早期版本的EJB 3.0規(guī)范的分析。它為我們提供了對(duì)于范規(guī)后面的基本原理的認(rèn)識(shí): 
http://www.javaworld.com/javaworld/jw-08-2004/jw-0809-ejb.html
●邁克爾.袁也進(jìn)行無(wú)線領(lǐng)域的開發(fā)。請(qǐng)查看他過(guò)去在JavaWorld的無(wú)線Java專欄中的文章: 
http://www.javaworld.com/columns/jw-wireless-index.shtml
●查看更多的有關(guān)Java EE的文章,請(qǐng)瀏覽在JavaWorld的頂層索引中的Java 2 Platform, Enterprise Edition (J2EE) 部分: 
http://www.javaworld.com/channel_content/jw-j2ee-index.shtml? (出處:http://m.survivalescaperooms.com)