一對多和多對一關(guān)系在實(shí)際生活中是非常常見的。在編寫程序時,有兩種實(shí)現(xiàn)的形式
分別是單向關(guān)聯(lián)和雙向關(guān)聯(lián)。
單向關(guān)聯(lián)
雙向關(guān)聯(lián)
本節(jié)中使用到兩個類,分別是班級(Team)和學(xué)生(Student),學(xué)生和班級之間是多對一
關(guān)系。
具體的關(guān)聯(lián)實(shí)現(xiàn)源代碼如下:
Student.hbm.xml
...
<hibernate-mapping>
<class name="model.Student" table="student">
<id name="id" unsaved-value="null">
<generator class="uuid.hex"/>
</id>
<property name="name" type="string'/>
<many-to-one name="team"
class="model.Team"
column="team_id" <!--和team發(fā)生關(guān)聯(lián)的列名-->
cascade="none"
fetch="join"
/>
</class>
</hibernate-mapping>
<many-to-one>標(biāo)簽具有column屬性,column屬性總是和關(guān)聯(lián)類(對于Student來說,關(guān)聯(lián)類
是Team)的主鍵id 相對應(yīng),因此Hibernate會根據(jù)student表中的team_id,根據(jù)Team表中設(shè)置
的id列(一般情況列名也叫id),取出team.id=student.team_id的記錄,構(gòu)造成Team對象返
回給Student類。
Team.hbm.xml
...
<hibernate-mapping>
<class name="model.Team" table="team" lazy="true">
<id name="id" unsaved-value="null">
<generator class="uuid.hex"/>
</id>
<property name="teamName" type="string"/>
<set name="students" cascade="save-update" lazy="true" inverse="true">
<key column="team_id"/>
<one-to-many class="model.Student"/>
</set>
</class>
</hibernate-mapping>
Team對Student是一對多關(guān)系,一對多具有<key column=""/>屬性,key標(biāo)簽總是和本身類的主鍵
相對應(yīng)。在取得Team對象時,通過Team的主鍵id與Student表中的team_id進(jìn)行匹配,如果
team.id=student.team_id,則認(rèn)為此學(xué)生是本班級的,于是加載學(xué)生,把學(xué)生對象加入Team
對象的學(xué)生集合。
設(shè)置inverse標(biāo)簽
由于在Team.hbm.xml中設(shè)置了inverse="true",Team和Student之間的關(guān)系轉(zhuǎn)由Student來維護(hù)
因此,當(dāng)Team掌握維護(hù)權(quán)時(inverse="false"或者默認(rèn)狀態(tài)),它負(fù)責(zé)將自己的id告訴Student
,然后Hibernate發(fā)送update語句去更新記錄。但現(xiàn)在設(shè)置了inverse="true"之后,維護(hù)權(quán)在
Student手中,于是Hibernate不再發(fā)送update語句,而由Student自動去取得team_id,而這個
動作其實(shí)就是完成一個“學(xué)生添加班級”動作,也就是語句newStu.setTeam(team)。