1
OK,上一篇已經介紹了專案開發的前期準備工作,具體內容可以參考:http://www.cnblogs.com/souvenir/p/3783686.html
按照開發步驟,我們現在已經可以開始進行業務邏輯元件層的開發工作了。但是之前只寫了一個bean,而且結構也相對很簡單,對於大型專案來說肯定是不夠的,所以
本章節的重點就是來建立更多的bean物件,為後面的邏輯元件開發做好準備工作。
對了,忘了介紹,我們是根據書上需求,準備做一個簡單的HR系統,包括簡單的請假,查工資等功能。
2
有人肯定疑惑了,之前已經做了一個bean的參考,其他的bean照著做不就行了嗎,為什麼還要單獨講。
好吧,之前的employee只是一個非常簡單的bean,在現實的開發專案中肯定有很多關係複雜的bean,我們要通過hibernate以及spring來完成對
他們的管理和呼叫。ok,話不多少,下面開始吧。
3
現在我們做一個員工工資實體物件,具體屬性包括id,emp,year,month,amount。
先完成payment物件:
對了,這裡bean物件實現了Serializable介面,主要為了方便物件的例項化,不清楚的可以百度一下。
public class Payment implements Serializable{ private static final long serialVersionUID = 99L; private int id; private Employee emp; private int year; private int month; private double salary; }
篇幅問題,我們省略了各屬性的set與get方法以及物件的建構函式。
這個bean和之前的employee沒有什麼大的區別,主要是多了一個對其他物件的引用。
4
建立好bean物件以後,我們來建立hibernate對映檔案。
<hibernate-mapping package="com.souvenir.bean"> <class name="Payment" table="Payment"> <!-- 對映標識屬性 --> <id name="id" column="payment_id" type="int"> <!-- 指定主鍵生成器策略 --> <generator class="identity"/> </id> <!-- 對映普通屬性 --> <property name="year" type="int"/> <property name="month" type="int"/> <property name="salary" type="double"/> <many-to-one name="emp" class="Employee" lazy="false" not-null="true" column="emp_id"/> </class> </hibernate-mapping>
OK,唯一需要強調的就是對emp這個物件的處理。員工的工資物件與員工應該是多對一的關係,因為一個員工可以有多份工資嘛。
所以這裡用了<many-to-one>來完成與emp的對映,使用class來指定其關聯的物件類名,同時可以指定其在資料庫表中的列名。
這樣就基本上完成了。
需要提個醒的是,也是樓主剛開始犯錯的地方,這裡配置檔案的name屬性一定要和你定義的bean java檔案中的屬性名稱一致,要不然系統會
提示找不到對應的set/get函式。
5 雙向1-N關聯配置
對於1-N的關聯關係,hibernate是推薦使用雙向1-N關聯配置,因為可以方便互相呼叫。
在本例中,employee就是1,payment就是N端,要實現二者的相互關聯,需要如下設定:
1端bean增加Set<N端>屬性,以及相應的get/set函式
N端bean增加1端的物件屬性,以及對應的get/set函式
這裡payment我們已經新增了employee的屬性,對於之前編寫的employee類來說,我們也需要增加Set<Payment>配置
private Set<Payment> payments= new HashSet<Payment>();
對於hibernate xml配置,employee也要做相應的調整:
<!-- 對映和Payment之間的關聯關係 --> <set name="payments" inverse="true" lazy="false"> <key column="emp_id" /> <one-to-many class="Payment"/> </set>
對應雙向1-N的關聯關係來說,一般是通過控制N端進行關聯關係控制,所以這裡我們把1端employee加上inverse=true屬性
兩個配置檔案中的one-to-many以及many-to-one的column值需要保持一致,hibernate通過這個值進行表的關聯。
上面我們用的是沒有關聯表的配置,大家也可以嘗試通過關聯表來實現,效果都一樣,只是資料庫中對出現一箇中間的關聯連線表。
6 還是測試
完成上述開發以後,我們就可以在main函式裡面進行測試了。
1.資料的建立:由於是雙向1-N關聯,所以通過N端進行關聯控制。體現在程式碼實現過程中就是先建立好N端物件,然後往N端物件中設定1端物件。
for(int i=1;i<=10;i++){ System.out.println("oooo==="+i); empDao.save(new Employee("souvenir"+i,i+1,"password"+i)); } Employee emp=empDao.get(2); //雙向1-N 讓N端來控制關聯關係 for(int j=1;j<=12;j++){ Payment payment=new Payment(2014,j,j*1002); payment.setEmp(emp); payDao.save(payment); }
上述程式碼主要實現以下功能:先建立10個employee物件,然後取出其中一個,然後建立12個payment物件,並將其全部的employee屬性都設定同一個。
2.既然是雙向連線,也就是說我們通過任一一端都可以取到對應的另一端。比如先通過N(payment)端訪問1(employee)端
Payment payment=payDao.get(2);
System.out.println(payment.getEmp().getName()+"--"+payment.getEmp().getPassword());
我們先拿一個N端物件payment,然後通過get函式取到employee物件。
3.通過1(employee)端訪問N(payment)端
Set<Payment> payments=empDao.get(2).getPayments();
for(Payment p: payments){
System.out.println(p.getYear()+"-"+p.getMonth()+":"+p.getSalary());
}
也就是說,我們通過人找到其對應的所有payment物件,這種業務也是比較常見的。