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>