Hibernate映射關係概述:java
Hibernate關聯映射分爲:數據庫
①、多對一。②、一對多。③、一對一。④、多對多。⑤、組件映射。⑥、集合映射。app
在Uml語言中關聯是有方向的,以客戶Customer和訂單Order的關係爲例,一個客戶能發出多個訂單,而一個訂單隻能屬於一個客戶。從Order到Customer的關聯是多對一,這意味着每一個Order對象都會引用一個Customer對象,所以在Order類中應該定義一個Customer類型的屬性,來引用關聯的Customer對象。從Customer到Order是一對多關聯,這意味着每一個Customer對象會引用一組Order對象,所以在Customer類中應該定義一個集合類型的屬性,來引用全部關聯的Order對象。若是僅有從Order到Customer的關聯,或者僅有從Customer到Order的關聯,就稱爲單向關聯。若是同時包含兩種關聯,就稱爲雙向關聯。函數
在關係數據庫中,只存在外鍵參照關係,並且老是由many方參照one方,由於這樣才能消除數據冗餘,所以實際上關係數據庫只支持多對一或一對一的單向關聯。ui
1、多對一的單向關聯關係:<many-to-one> this
一、 在Order類中定義一個customer屬性,而在Customer類中無需定義用於存放Order對象的集合屬性。咱們在Order類中能夠定義customer_id屬性,可是沒有多大意義,不方便。因此咱們在Order類中定義的customer屬性時Customer類型的,和Orders表的外鍵customer_id對應,因此下面的映射方式是錯誤的:spa
<property name="customer" column="customer_id" /> 這種映射方式是錯誤的。
在上面的配置代碼中,customer屬性是Customer類型,而Orders表的外鍵customer_id是整數類型,顯然類型不匹配,所以不能使用<property>元素來映射customer屬性,而要使用<many-to-one>元素hibernate
<many-to-one name="customer" column="customer_id" class="Com.edu.bean.Customer" nut-null="true"/>
name:設置持久化類的屬性名。code
column:設定和持久化類的屬性對應的表的外鍵。xml
class:設定持久化類的屬性的類型。
not-null:若是爲true,表示customer屬性不容許爲null,該屬性的默認值爲false。
Order類和Customer類分別以下:
public class Customer{ private String cid; private String cname; public Customer(){} //持久化類必須提供默認的構造函數 public Customer(String cid,String cname){ this.cid=cid; this.cname=cname; } public String getCid() { return cid; } public void setCid(String cid) { this.cid = cid; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } }
Customer.hbm.xml文件:
<hibernate-mapping package="com.edu.bean"> <class name="Customer" table="sys_customer"> <id name="cid" column="cid"> <generator class="assigned"></generator> </id> <property name="cname" column="cname" ></property> </class> </hibernate-mapping>
Order類:
package com.edu.bean; public class Order { private String oid; private String oname; private Customer customer; public Order(){} public String getOid() { return oid; } public void setOid(String oid) { this.oid = oid; } public String getOname() { return oname; } public void setOname(String oname) { this.oname = oname; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } }
Order.hbm.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.edu.bean"> <class name="Order" table="sys_order"> <id name="oid" column="oid"> <generator class="assigned"></generator> </id> <property name="oname" column="oname" ></property> <many-to-one name="customer" column="customerId" class="Customer"></many-to-one> </class> </hibernate-mapping>
2、一對多的單向關聯關係:<one-to-many>
一、咱們如今的業務需求常常要得到某個customer對象的全部order,因此爲了方便起見咱們採用Hibernate的多對已關聯關係,在Customer類中,定義Set<order>order集合。
如今Customer類修改以下:
public class Customer{ private String cid; private String cname; private Set<Order> orders; public Set<Order> getOrders() { return orders; } public void setOrders(Set<Order> orders) { this.orders= orders; } public Customer(){} //持久化類必須提供默認的構造函數 public Customer(String cid,String cname){ this.cid=cid; this.cname=cname; } public String getCid() { return cid; } public void setCid(String cid) { this.cid = cid; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } }
Customer.hbm.xml文件修改以下:
<hibernate-mapping package="com.edu.bean"> <class name="Customer" table="sys_customer"> <id name="cid" column="cid"> <generator class="assigned"></generator> </id> <property name="cname" column="cname" ></property> </class> <set name="orders"> <key column="customerId"/> <one-to-many class="Order"> </one-to-many> </set> </hibernate-mapping>
3、一對一關聯關係
Hibernate的一對第一關聯關係有兩種實現方式:共享主鍵方式和惟一外鍵方式。在這種一對一關聯關係中對象分爲主對象和從對象。
一、基於主鍵的一對一關聯關係:
例如Person人只有一個身份證Idcard,Person和IdCard是一對一的關係:
Person類:
package com.edu.bean; public class Person { private String id; private String name; private IdCard idcard; public Person(){} public Person(String id,String name,IdCard idcard){ this.id=id; this.name=name; this.idcard=idcard; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public IdCard getIdcard() { return idcard; } public void setIdcard(IdCard idcard) { this.idcard = idcard; } }
Person.hbm.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.edu.bean"> <class name="Person" table="sys_person"> <id name="id" column="id"> <generator class="assigned"></generator> </id> <property name="name" column="name" ></property> <one-to-one name="idcard"></one-to-one> </class> </hibernate-mapping>
IdCar類:
package com.edu.bean; public class IdCard { private String id; private String username; private Person person; public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }
IdCard.hbm.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.edu.bean"> <class name="IdCard" table="sys_idcard"> <id name="id" column="id"> <generator class="foreign"> <param name="property">person</param> </generator> </id> <property name="username" column="username" ></property> <one-to-one name="person" class="Person" constrained="true"></one-to-one> </class> </hibernate-mapping>
這裏使用Hibernate的constrained屬性,這個屬性只能在<one-to-one>的映射中使用,若是constrained=true,則代表該類對應的表和被關聯的對象所對應的數據庫之間,經過一個外鍵引用對主鍵進行約束。這個選項影響save()和delete()在級聯執行時的前後順序。例如在save的時候,若是constrained=true,則會先增長關聯表,而後增長本表,刪除的時候相反。
二、基於外鍵的一對一關聯關係:
Person類及Person.hbm.xml文件沒有任何變化:
IdCard類:
package com.edu.bean; public class IdCard { private String id; private String username; private Person person; public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }
IdCard.hbm.xml文件以下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.edu.bean"> <class name="IdCard" table="sys_idcard"> <id name="id" column="id"> <generator class="assigned"> </generator> </id> <property name="username" column="username" ></property> <many-to-one name="person" column="p_id" class="Person" unique="true"></many-to-one> <!-- <one-to-one name="person" class="Person" constrained="true"></one-to-one> --> </class> </hibernate-mapping>
4、多對多關聯關係:
在關係型數據庫中實體多對多時,咱們通常建立中間關聯表,而Hibernate一樣也會爲咱們建立中間關聯表,將多對多拆分爲2個一對多。
例如經典的用戶角色問題:
用戶User類:
package com.edu.bean; import java.util.Set; public class User { private String uid; private String uname; private String password; private Set<Role> roles; public User(){} public User(String uid,String uname,String password){ this.uid=uid; this.uname=uname; this.password=password; } public String getUid() { return uid; } public void setUid(String uid) { this.uid = uid; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Set<Role> getRoles() { return roles; } public void setRoles(Set<Role> roles) { this.roles = roles; } }
User.hbm.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.edu.bean"> <class name="User" table="sys_user"> <id name="uid" column="uid"> <generator class="assigned"></generator> </id> <property name="uname" column="uname" ></property> <property name="password" column="password"></property> <set name="roles" table="user_role"> <key column="uid"></key> <many-to-many class="Role" column="rid"></many-to-many> </set> </class> </hibernate-mapping>
角色類Role:
package com.edu.bean; import java.util.Set; public class Role { private String rid; private String rname; private Integer ordernum; private String description; private Set users; public Role(){} public Role(String rid,String rname,Integer ordernum,String description){ this.rid=rid; this.rname=rname; this.ordernum=ordernum; this.description=description; } public String getRid() { return rid; } public void setRid(String rid) { this.rid = rid; } public String getRname() { return rname; } public void setRname(String rname) { this.rname = rname; } public Integer getOrdernum() { return ordernum; } public void setOrdernum(Integer ordernum) { this.ordernum = ordernum; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Set getUsers() { return users; } public void setUsers(Set users) { this.users = users; } }
Role.hbm.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.edu.bean"> <class name="Role" table="sys_role"> <id name="rid" column="rid"> <generator class="assigned"></generator> </id> <property name="rname" column="rname" ></property> <property name="ordernum" column="ordernum"></property> <property name="description" column="description"></property> <set name="users" table="user_role"> <key column="rid"></key> <many-to-many class="User" column="uid"></many-to-many> </set> </class> </hibernate-mapping>