今天內(nèi)容為兩個版塊JPA與EJB,從學習hibernate、UML到JPA。他們都涉及到一個極為重要的細節(jié)——類與類、接口與接口或類與接口之間的四類關(guān)聯(lián)關(guān)系。今日上午到下午3點左右內(nèi)容為JPA中處理這四類關(guān)系。我想我應該將他們系統(tǒng)的做一下總結(jié),這項任務就留著后天休息來完成吧!
近三天的課程內(nèi)容除了帶給我知識上的獲取和見識的增長,更讓我感覺到一種力量!在學習WEB之前,這些互聯(lián)網(wǎng)的東西讓我滿頭霧水,不知所云。但在傳智播客學習到現(xiàn)在,WEB應用中應該沒什么還能讓我滿頭霧水的了,云計算也沒之前那么讓我感到神秘的。帶給我什么力量了?一種駕馭知識的力量!我十分有興與兩位高手租房子,我從他們身上學習到了很多知識。因為我沒讀過本科,所以計算機基礎知識不夠好。偶有時間,看一看計算機組成原理等。通過與同學的交流,我似乎已經(jīng)能摸清硬件了執(zhí)行原理,并不復雜。
通過以前的工作自己掌握的知識、在傳智播客學習到的知識,以及與同事、好友、同學們的相處。我似乎已經(jīng)感覺到將硬件、桌面應用、WEB應用...融匯貫通的感覺!這感覺讓我充滿力量。
一、JPA中的關(guān)聯(lián)關(guān)系
說實在的在學習hibernate和UML時,聽著老師講關(guān)聯(lián)關(guān)系一點問題都沒有。但他們在我腦子里沒形成系統(tǒng)的概念。但今天學習JPA的關(guān)聯(lián)關(guān)系,讓我找到了感覺。關(guān)系關(guān)聯(lián)在我腦子里形成系統(tǒng)的概念,指日可待!
1.一對多單向關(guān)聯(lián)
典型的例子是,客戶與訂單這種一對多的關(guān)系。在客戶類的orders屬性或getOrders屬性方法上添加注解:
@OneToMany(fetch=FetchType.EAGER, cascade={CascadeType.PERSIST,CascadeType.REMOVE}, targetEntity=Order.class) |
“@OneToMany”表示一對多關(guān)聯(lián)關(guān)系的注解,括號內(nèi)全是他的屬性。
“fetch=FetchType.EAGER”,強迫左外連接,默認值為“LAZY”。
“cascade={CascadeType.PERSIST,CascadeType.REMOVE}”,設置保存和刪除級聯(lián)。
“targetEntity=Order.class”,相當于hibernate的class屬性。
2.多對一單向關(guān)聯(lián)
訂單與客戶的例子。在訂單類的customer屬性或getCustomer屬性方法上添加注解:
@ManyToOne(cascade={CascadeType.PERSIST}) @JoinColumn(name="cid") |
“@ManyToOne”表示多對一的關(guān)聯(lián)關(guān)系的注解,括號內(nèi)全是他的屬性。
“cascade={CascadeType.PERSIST}”設置保存級聯(lián)。
“@JoinColumn”設置Orders表的外鍵。
“name="cid"”外鍵的名稱。
3.一對多(多對一)雙向關(guān)聯(lián)
在客戶類的orders屬性或getOrders屬性方法上添加注解:
@OneToMany(mappedBy="customer", fetch=FetchType.EAGER, cascade={CascadeType.PERSIST,CascadeType.REMOVE}, targetEntity=Order.class) |
在訂單類的customer屬性或getCustomer屬性方法上添加注解:
在上面的注解中只“@OneToMany”中多了一個“mappedBy="customer"”屬性,它相當于hibernate的“inverse=false”屬性,不參與對集合的控制。如果不設置“mappedBy”屬性,JPA會為一對多關(guān)聯(lián)關(guān)系設置一個中間表。
4.一對一關(guān)聯(lián)
使用學習hibernate時的例子,用戶包含大文本信息的地址屬性。
外鍵關(guān)聯(lián):
在用戶表的Addr屬性或getAddr屬性方法上添加注解:
@ManyToOne(cascade={CascadeType.PERSIST}) @JoinColumn(name="cid") |
“@OneToOne”為一對一關(guān)聯(lián)關(guān)系注解。
“@JoinColumn”設置外鍵。
“name="aid"”外鍵名稱為“aid”。
“unique=true”外鍵唯一性,用戶與地址一一對應。
在地址表的User屬性或getUser屬性方法上添加注解:
@OneToOne @JoinColumn(name="aid",unique=true) |
“@OneToOne”為一對一關(guān)聯(lián)關(guān)系注解。
“mappedBy="addr"”取消對集合的控制權(quán),用User實體來控制外鍵的值。
主鍵關(guān)聯(lián):
在用戶表的Addr屬性或getAddr屬性方法上添加注解:
“@OneToOne”為一對一關(guān)聯(lián)關(guān)系注解。
“@PrimaryKeyJoinColumn”,設置主鍵關(guān)聯(lián)列。
“name="userid"”,本實體關(guān)聯(lián)字段的名稱。
“referencedColumnName="addrid"”,所關(guān)聯(lián)實體的表中的字段名稱。
在地址表的User屬性或getUser屬性方法上添加注解:
@OneToOne(mappedBy="addr") |
“@OneToOne”為一對一關(guān)聯(lián)關(guān)系注解。
“mappedBy="addr"”取消對集合的控制權(quán),用User實體來控制外鍵的值。
5.多對多關(guān)聯(lián)
經(jīng)典的例子,教師與學生多對多關(guān)聯(lián)關(guān)系。
在Teacher實體的stus集合屬性或getStus屬性方法上添加注解:
@OneToOne @PrimaryKeyJoinColumn(name="userid",referencedColumnName="addrid") |
“@ManyToMany”設置多對多關(guān)聯(lián)關(guān)系。
“@JoinTable”設置關(guān)聯(lián)表。
“name="jpa_links"”中間表表名。
“joinColumns=@JoinColumn(name="tid")”設置Teacher實體對應的關(guān)聯(lián)列。數(shù)組類型,可以設置多重主鍵。
“inverseJoinColumns=@JoinColumn(name="sid")”設置Student實體對應的關(guān)聯(lián)列。數(shù)組類型,可以設置多重主鍵。
在Student實體的teas集合屬性或getTeas屬性方法上添加注解:
@OneToOne(mappedBy="addr") |
“@ManyToMany”為多對多關(guān)聯(lián)關(guān)系注解。
“mappedBy="addr"”取消對集合的控制權(quán)。
6.繼承關(guān)系
繼承關(guān)系有三種解決方法,我們?nèi)匀皇褂脤W習hibernate時所使用的例子。一個員工實體(Employee),一個鐘點工子實體(HourlyEmployee)和一個薪水工子實體(SalaryEmployee)。
1).繼承關(guān)系樹對應一張表
在Employee實體類上面添加注解:
@ManyToMany @JoinTable(name="jpa_links", joinColumns=@JoinColumn(name="tid"), inverseJoinColumns=@JoinColumn(name="sid")) |
“@Entity”設置實體。
“@Table(name="jpa_inherit_single_ess")”設置表名。
“@Inheritance(strategy=InheritanceType.SINGLE_TABLE)”設置集成策略為單個表,將整個繼承關(guān)系樹保存在一張表中。
“@DiscriminatorColumn(name="type",discriminatorType=DiscriminatorType.STRING)”設置區(qū)分器字段名稱和類型。
“@DiscriminatorValue("ee")”Employee對應的區(qū)分類型值為“ee”。
在HourlyEmployee實體類上面添加注解:
@ManyToMany(mappedBy="stus") |
“@Entity”設置實體。
“@DiscriminatorValue("he")”Employee對應的區(qū)分類型值為“he”。
在SalaryEmployee實體類上面添加注解:
@Entity @Table(name="jpa_inherit_single_ess") @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="type",discriminatorType=DiscriminatorType.STRING) @DiscriminatorValue("ee") |
“@Entity”設置實體。
“@DiscriminatorValue("se")”Employee對應的區(qū)分類型值為“se”。
2).每個類對應一張表,使用外鍵關(guān)聯(lián)。
在Employee實體類上面添加注解:
“@Entity”設置實體。
“@Table(name="jpa_inherit_join_ees")”設置表名。
“@Inheritance(strategy=InheritanceType.JOINED)”設置集成策略為聯(lián)合,為繼承關(guān)系樹中每個成員創(chuàng)建一個表,并使用外鍵關(guān)聯(lián)(父類的主鍵被做為子類的外鍵)。
在HourlyEmployee實體類上面添加注解:
@Entity @DiscriminatorValue("he") |
“@Entity”設置實體。
“@Table(name="jpa_inherit_join_hes")”設置表名。
“@PrimaryKeyJoinColumn(name="eeid")”設置外鍵。
在SalaryEmployee實體類上面添加注解:
@Entity @DiscriminatorValue("se") |
“@Entity”設置實體。
“@Table(name="jpa_inherit_join_ses")”設置表名。
“@PrimaryKeyJoinColumn(name="eeid")”設置外鍵。
3).聯(lián)合表,每個類單獨一個表,使用union聯(lián)合。
在Employee實體類上面添加注解:
@Entity @Table(name="jpa_inherit_join_ees") @Inheritance(strategy=InheritanceType.JOINED) |
“@Entity”設置實體。
“@Table(name="jpa_inherit_join_ess")”設置表名。
“@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)”設置集成策略為union,為繼承關(guān)系樹中的每個成員創(chuàng)建一張表,每個表包含全信息(子類表中包含父類屬性的字段)。
在HourlyEmployee實體類上面添加注解:
“@Entity”設置實體。
在SalaryEmployee實體類上面添加注解:
@Entity @Table(name="jpa_inherit_join_hes") @PrimaryKeyJoinColumn(name="eeid") |
“@Entity”設置實體。
二、EJB3簡介
在本文中將對新的規(guī)范進行一個概要性的介紹,包括新增的元數(shù)據(jù)支持,EJBQL的修改,實體Bean模型訪問bean上下文的新方法和運行時環(huán)境等等。作者還討論了EJB在未來要作出的調(diào)整以及EJB3.0與其他開發(fā)規(guī)范之間的關(guān)系。
來自:http://developer.51cto.com/art/200510/6284.htm
三、EJB3“HelloWorld!”
我們使用EJB3編寫一個“HelloWorld!”程序:
一、配置JBOSS服務器
1.我們使用的是“jboss-4.2.2.GA”。
2.將“jboss-4.2.2.GA”放置在非中文路徑目錄。、
3.添加環(huán)境變量“JBOSS_HOME”,值為“jboss-4.2.2.GA”所在目錄。
4.修改JBOSS服務器端口,配置文件為“jboss-4.2.2.GA\server\default\deploy\jboss-web.deployer\server.xml”。將其中的8080端口修改為8088端口。
5.在IDE中配置JBOSS服務器,指定JBOSS4.X服務器所在目錄。
二、EJB組件
1.創(chuàng)建一個普通Java工程,命名為“EJB3_HW_EJB”。
2.將hibernate3.1目錄下的“jpa”子目錄中的所有jar包導入到工程。
3.在工程中添加一個接口“cn.itcast.cc.ejb3.ejb.HelloWorld”:
@Entity @Table(name="jpa_inherit_join_ses") @PrimaryKeyJoinColumn(name="eeid") |
4.編寫一個“HelloWorld”接口的實現(xiàn)類“cn.itcast.cc.ejb3.ejb.HelloWorldImpl”:
@Entity @Table(name="jpa_inherit_join_ess") @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) |
@Entity |
5.將工程“EJB3_HW_EJB”導出為“EJB3_HW_EJB.jar”包。
6.將“EJB3_HW_EJB.jar”拷貝到“JBOSS”的“\server\default\deploy”目錄下,JBOSS服務器會自動部署。
三、WEB應用
1.創(chuàng)建一個WEB應用工程,命名為“EJB3_HW_WEB”。
2.將上邊的EJB組件工程“”添加為WEB應用工程的Required Project。(在“Configure Build Path”中設置)
3.將“index.jsp”頁面的內(nèi)容設置為:
@Entity |
import javax.ejb.Local; @Local public interface HelloWorld { String hello(String str); } |
import javax.ejb.Stateless; @Stateless public class HelloWorldImpl implements HelloWorld { public String hello(String str) { System.out.println(str); return "Hello "+str+" ,welcome to EJB3!"; } } |
4.將工程“EJB3_HW_WEB”導出為“EJB3_HW_WEB.war”包。
5.將“EJB3_HW_WEB.war”拷貝到“JBOSS”的“\server\default\deploy”目錄下,JBOSS服務器會自動部署。
四、運行
1.在IDE中啟動JBOSS服務器。
2.打開瀏覽器。
3.輸入URL“http://localhost:8088/EJB3_HW_WEB/index.jsp”。
4.在輸出容器中輸出:“23:15:51,683 INFO [STDOUT] changcheng”。
5.在JSP頁面中輸出:“Hello changcheng ,welcome to EJB3! ”
OK,今天的內(nèi)容到此結(jié)束!