Hibernate<四> Hibernate关联映射
2015-08-06 00:00
232 查看
摘要: 复习Hibernate 入门学习
Hibernate映射关系概述:
Hibernate关联映射分为:
①、多对一。②、一对多。③、一对一。④、多对多。⑤、组件映射。⑥、集合映射。
在Uml语言中关联是有方向的,以客户Customer和订单Order的关系为例,一个客户能发出多个订单,而一个订单只能属于一个客户。从Order到Customer的关联是多对一,这意味着每个Order对象都会引用一个Customer对象,因此在Order类中应该定义一个Customer类型的属性,来引用关联的Customer对象。从Customer到Order是一对多关联,这意味着每个Customer对象会引用一组Order对象,因此在Customer类中应该定义一个集合类型的属性,来引用所有关联的Order对象。如果仅有从Order到Customer的关联,或者仅有从Customer到Order的关联,就称为单向关联。如果同时包含两种关联,就称为双向关联。
在关系数据库中,只存在外键参照关系,而且总是由many方参照one方,因为这样才能消除数据冗余,因此实际上关系数据库只支持多对一或一对一的单向关联。
一、多对一的单向关联关系:<many-to-one>
1、 在Order类中定义一个customer属性,而在Customer类中无需定义用于存放Order对象的集合属性。我们在Order类中可以定义customer_id属性,但是没有多大意义,不方便。所以我们在Order类中定义的customer属性时Customer类型的,和Orders表的外键customer_id对应,所以下面的映射方式是错误的:
在上面的配置代码中,customer属性是Customer类型,而Orders表的外键customer_id是整数类型,显然类型不匹配,因此不能使用<property>元素来映射customer属性,而要使用<many-to-one>元素
name:设置持久化类的属性名。
column:设定和持久化类的属性对应的表的外键。
class:设定持久化类的属性的类型。
not-null:如果为true,表示customer属性不允许为null,该属性的默认值为false。
Order类和Customer类分别如下:
Customer.hbm.xml文件:
Order类:
Order.hbm.xml文件:
二、一对多的单向关联关系:<one-to-many>
1、我们现在的业务需求经常要获得某个customer对象的所有order,所以为了方便起见我们采用Hibernate的多对已关联关系,在Customer类中,定义Set<order>order集合。
现在Customer类修改如下:
Customer.hbm.xml文件修改如下:
三、一对一关联关系
Hibernate的一对第一关联关系有两种实现方式:共享主键方式和唯一外键方式。在这种一对一关联关系中对象分为主对象和从对象。
1、基于主键的一对一关联关系:
例如Person人只有一个身份证Idcard,Person和IdCard是一对一的关系:
Person类:
Person.hbm.xml文件
IdCar类:
IdCard.hbm.xml文件
这里使用Hibernate的constrained属性,这个属性只能在<one-to-one>的映射中使用,如果constrained=true,则表明该类对应的表和被关联的对象所对应的数据库之间,通过一个外键引用对主键进行约束。这个选项影响save()和delete()在级联执行时的先后顺序。例如在save的时候,如果constrained=true,则会先增加关联表,然后增加本表,删除的时候相反。
2、基于外键的一对一关联关系:
Person类及Person.hbm.xml文件没有任何变化:
IdCard类:
IdCard.hbm.xml文件如下:
四、多对多关联关系:
在关系型数据库中实体多对多时,我们一般创建中间关联表,而Hibernate同样也会为我们创建中间关联表,将多对多拆分为2个一对多。
例如经典的用户角色问题:
用户User类:
User.hbm.xml文件:
角色类Role:
Role.hbm.xml文件
Hibernate映射关系概述:
Hibernate关联映射分为:
①、多对一。②、一对多。③、一对一。④、多对多。⑤、组件映射。⑥、集合映射。
在Uml语言中关联是有方向的,以客户Customer和订单Order的关系为例,一个客户能发出多个订单,而一个订单只能属于一个客户。从Order到Customer的关联是多对一,这意味着每个Order对象都会引用一个Customer对象,因此在Order类中应该定义一个Customer类型的属性,来引用关联的Customer对象。从Customer到Order是一对多关联,这意味着每个Customer对象会引用一组Order对象,因此在Customer类中应该定义一个集合类型的属性,来引用所有关联的Order对象。如果仅有从Order到Customer的关联,或者仅有从Customer到Order的关联,就称为单向关联。如果同时包含两种关联,就称为双向关联。
在关系数据库中,只存在外键参照关系,而且总是由many方参照one方,因为这样才能消除数据冗余,因此实际上关系数据库只支持多对一或一对一的单向关联。
一、多对一的单向关联关系:<many-to-one>
1、 在Order类中定义一个customer属性,而在Customer类中无需定义用于存放Order对象的集合属性。我们在Order类中可以定义customer_id属性,但是没有多大意义,不方便。所以我们在Order类中定义的customer属性时Customer类型的,和Orders表的外键customer_id对应,所以下面的映射方式是错误的:
<property name="customer" column="customer_id" /> 这种映射方式是错误的。
在上面的配置代码中,customer属性是Customer类型,而Orders表的外键customer_id是整数类型,显然类型不匹配,因此不能使用<property>元素来映射customer属性,而要使用<many-to-one>元素
<many-to-one name="customer" column="customer_id" class="Com.edu.bean.Customer" nut-null="true"/>
name:设置持久化类的属性名。
column:设定和持久化类的属性对应的表的外键。
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>
二、一对多的单向关联关系:<one-to-many>
1、我们现在的业务需求经常要获得某个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>
三、一对一关联关系
Hibernate的一对第一关联关系有两种实现方式:共享主键方式和唯一外键方式。在这种一对一关联关系中对象分为主对象和从对象。
1、基于主键的一对一关联关系:
例如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,则会先增加关联表,然后增加本表,删除的时候相反。
2、基于外键的一对一关联关系:
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>
四、多对多关联关系:
在关系型数据库中实体多对多时,我们一般创建中间关联表,而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>
相关文章推荐
- 常用css
- Git 使用规范流程
- 用Python写一个ftp下载脚本
- 抽象类的作用(转)
- 开始啃 AngularJS
- TypeScript 语言学习
- 不好的JS脚本(编译器无法优化)
- 天下数据分析服务器配置方案
- 如何在开源中国人才网进行“企业认证”
- 账号管理:如何添加副招聘官
- 使用Eclipse构建Maven项目 (step-by-step)
- 启动一个新的container
- Android之应用首次使用的欢迎界面实例
- VIM 快速参考指南
- 光纤终端指示器
- Request学习笔记
- sql 高级 (五)(create index(创建索引) drop)
- Proxy Design Pattern(代理模式)
- 游戏更新
- Mac Yosemite安装配置nginx+php+mysql+memcached环境