在設計數據庫時咱們會考慮,表與表之間的關係,例如咱們前邊常常提到的一對一,一對多,多對多關係,在數據庫中咱們經過外鍵,第三張表等來實現這些關係。而Hibernate時間實體類和數據庫中的表進行的映射,這些關係如何映射呢?這裏簡單總結一下: java
一,一對多,多對一關係映射,這裏拿學生和班級進行簡單演示: node
1,學生的類和對應的映射文件的編寫: 數據庫
private int sid ; private String sname ; private Classes classes ; //,引入班級對象,多對一
<class name="com.ljh.hibernate.pojo.Student" table="t_student" lazy="false"> <id name="sid" column="sid"> <generator class="native"/> </id> <property name="sname" column="sname" type="java.lang.String" length="20" not-null="true"/> <!-- 表示對象的關係:多對一 name 表示當前類的關係對象 column 表示數據庫中外鍵字段(也是描述數據關係) class 表示name屬性值的類型 cascade 級聯 主動方所作的操做(insert,update,delete),被動方也跟着作相同的操做。 取值:save-update、delete 、all save-update : 保存或更新當前對象時,級聯保存或更新關聯對象 delete : 刪除當前對象時,級聯刪除關聯對象 all : 包含save,update,delete三種操做。 對於多對一的場合,級聯不能使用delete和all,不然會違背數據關係完整性。 lazy : 延遲加載 延遲初始化對象信息,等使用對象時再查詢數據庫。 false : 禁用延遲加載 proxy : 使用延遲加載(默認值),採用cglib代理完成延遲加載的擴展功能。 no-proxy : 不使用代理,完成延遲加載 。可使用第三方字節碼加強工具。 fetch : 數據抓取策略 :根據主動方,查詢被動方時所採用的查詢方式。 fetch="select" 默認值,會採用多條語句的方式查找,每每會延遲加載數據 fetch="join" 默認會採用左鏈接查詢數據,不會延遲加載數據。 not-null 若是取值爲true,那麼框架採用內鏈接查詢數據。 --> <many-to-one name="classes" column="cid" cascade="save-update" lazy="no-proxy" fetch="join" not-null="true" class="com.ljh.hibernate.pojo.Classes"></many-to-one> </class>
2,班級的實體類和對應的映射文件: 框架
private int cid ; private String cname ; private Set<Student> studentSet = new HashSet<Student>(); //引入學生類的集合,一對多
<class name="com.ljh.hibernate.pojo.Classes" table="t_classes" > <id name="cid" column="cid"> <generator class="native"/> </id> <property name="cname" column="cname" type="java.lang.String" length="20" not-null="true"/> <!-- 聲明 一對多映射 lazy : 延遲加載 false : 禁用延遲加載 true : 延遲加載(默認值) extra : 支持延遲加載的。(推薦) 當獲取集合自身信息時,能夠發送高效的查詢語句。 例如:只但願獲取集合的長度,而不須要獲取集合中數據的信息,框架會經過函數執行查詢進行計算集合長度。。 fetch : 數據抓取策略 查詢關聯對象的數據時,所採用的查詢方式。 join : 經過一條鏈接語句進行當即查詢。(延遲加載不起做用) select : 經過多條查詢語句進行查詢。 subselect : 經過子查詢語句進行當即查詢。 (不推薦使用)(默認狀況下和select取值結果相同) not-null="true" 對於一對多的查詢,即便設置了not-null語句,依然採用左鏈接查詢。 Inverse="true",表示控制反轉,由對方也就是學生方來進行管理外鍵。由於外鍵在學生 --> <set name="studentSet" cascade="all" inverse="true" fetch="subselect"> <key column="cid" not-null="true"></key> <one-to-many class="com.bjpowernode.hibernate.pojo.Student"/> </set> </class>
private int mid ; private String name ; private Set<Menu> menuSet = new HashSet<Menu>(); //父菜單與子菜單的關係爲:一對多 private Menu pmenu ; //子菜單和父菜單的關係爲:多對一
<class name="com.ljh.hibernate.pojo.Menu" table="t_menu" > <id name="mid" column="mid"> <generator class="native"/> </id> <property name="name" column="name" type="java.lang.String" length="20" not-null="true"/> <many-to-one name="pmenu" column="m_id" cascade="save-update"></many-to-one> <!-- 自關聯表的設計:外鍵字段不能爲非空。 --> <set name="menuSet" cascade="all" inverse="true"> <key column="m_id"></key> <one-to-many class="com.ljh.hibernate.pojo.Menu"/> </set> </class>
三,一對一關係映射: 函數
1,假如是主鍵一對一用來映射:也就是說被動方的主鍵是來自於主動方的主鍵,也能夠將之稱之爲外鍵: 工具
類之間相互添加彼此的應用。 fetch
映射文件中主動方,增長一對一標籤: ui
<one-to-one name="userinfo" cascade="all" class="com.ljh.hibernate.pojo.UserInfo"></one-to-one> 被動方,主鍵又是外鍵,也添加一對一的映射標籤: <id name="uid" column="uid"> <generator class="foreign"> <param name="property">user</param> </generator> </id> <!-- 描述一對一關係關係映射 constrained="true" : 表示強制要求一對一使用外鍵關聯。增長外鍵約束。 --> <one-to-one name="user" constrained="true" class="com.ljh.hibernate.pojo.User"></one-to-one>
類添加彼此的應用。 spa
映射文件中學生端主動端,添加外鍵進行約束,添加多對一標籤, hibernate
<!-- unique : 惟一約束 若是外鍵含有unique約束,那麼表示主動方和被動方的關係爲一對一。 對於一對一映射來說,能夠設置級聯關係爲delete 和 all 根據主動方查詢被動方關聯數據,是支持延遲加載的。 --> <many-to-one name="classes" column="cid" unique="true" cascade="all" class="com.ljh.hibernate.pojo.Classes"></many-to-one> 班級端的映射文件:添加一對一的標籤: <one-to-one name="student" cascade="all" property-ref="classes" class="com.ljh.hibernate.pojo.Student"></one-to-one>
四,多對多的關係,例如學生對課程的對應,在數據庫中會生成第三張表進行維護:
在各自的類中引入對方的set集合,表示多對多。
學生端:
<set name="courseSet" table="t_student_course" cascade="save-update"> <key column="sid"></key> <many-to-many class="com.ljh.hibernate.pojo.Course" column="cid"></many-to-many> ;/set>
課程端:
<set name="courseSet" table="t_student_course" cascade="save-update"> <key column="sid"></key> <many-to-many class="com.ljh.hibernate.pojo.Course" column="cid"></many-to-many> ;/set>
五,聯合主鍵的映射,這種狀況不多見,看一下如何吧,
出現了這種聯合鍵時,須要咱們爲其定義一個聯合主鍵的類(實現Serializable接口),類中聲明多個字段的屬性,表示聯合主鍵字段。
在配置映射文件時,主鍵的配置利用聯合主鍵的標籤便可:
<composite-id name="id"> <key-property name="title"></key-property> <key-property name="author"></key-property> </composite-id>