hibernate--关系映射

一下讲的是对象之间的数量关系,而数据库的表间关系就一种,就是外键
Hibernate的关联关系映射大概有这么几种: 1、单向N-1 2、单向1-1 3、单向1-N 4、单向N-N 5、双向1-N 6、双向N-N 7、双向1-1 下面就对这七种关联关系映射进行一个简单的总结: 一、单向的多对一 看两个POJO public class Person{ private int pid; private String name; private Address address; ...//生成相应的getter、setter方法 } ---------------------------------------- public class Address{ private int id; private String detail; ...//生成相应的getter、setter方法 } 这里我们需要维护的关系是多个Person可以对应同一个地址,使用单向的N-1映射我们只需要在多的一端加入一个外键指向一的一端即可 **看配置文件 <class name="Person"> <id name="id"> <generator class="native"/> </id> ...//部分字段配置省略 <many-to-one name="address" column="addressId"/>//关键配置 </class> 这样配置以后hibernate就会帮我们在多的一端(Person)添加一个外键addressId指向一的一端 二、单向的1-1(外键关联) 可以采用<many-to-one>标签,指定多的一端的unique=true,这样就限制了多的一端的多重性唯一 通过这种手段映射一对一唯一外键关联 配置文件只需要修改为: <many-to-one name="address" column="addressId" unique="true"/> 三、单向的1-N **看代码,我们知道一个班级有多名学生,这就是一个典型的1-N关系 public class Classes { private int id; private String name; private Set students; ...//生成相应的getter、setter方法 } --------------------------------------------------------------------------- public class Student { private int id; private String name; ..//生成相应是getter、setter方法 } **映射原理:一对多关联映射,在多的一端添加一个外键指向一的一端,它维护的关系是一指向多 **配置文件: <class name="Classes" table="t_classes"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <set name="students"> <key column="classesid"/>//在一的一端添加的外键指向多的一端(默认情况下市主键匹配) <one-to-many class="xxx.Student"/>//注意它维护的是一指向多的关系 </set> </class> 四、双向1-N 上面提到了单向的1-N在一的一端添加的外键指向多的一端即可,对于双向的1-N则类似于N-N,集合元素中不使用<one-to-many> 元素映射关联属性,而使用<many-to-many>元素,但是为了保证一的一端,因此需要增加unique="true"属性 **配置,简单修改单向1-N的配置文件 <class name="xxx.Classes" table="t_classes"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <set name="students"> <key column="classesid"/> <many-to-many class="xxx.Student" unique="true"/> </set> </class> 五、单向多对多 **先看两个POJO public class User { private int id; private String name; private Set roles; ..//生成相应的getter、setter方法 } --------------------------------------------------------------------------- public class Role { private int id; private String name; ..//生成相应的getter、setter方法 } 现在需要映射这样的N-N关系,一个User可以有多个Role,而一个Role有可以被多个User所拥有 这样我们就可以将一个N-N关系拆分为两个N-1的关系 **看配置文件 <class name="xxx.User" table="t_user"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <set name="roles" table="t_user_role"> <key column="userid"/> <many-to-many class="xxx.Role" column="roleid"/> </set> </class> 这样我们的关系的明确了 t_user t_user_role t_role id name < -------userid roleid ----- > id name 六、双向的多对多关系 双向的多对多映射需要在两边都增加集合元素,用于映射集合属性 修改上面的单向N-N映射 在Role中添加集合属性 public class Role { private int id; private String name; privarte Set user ..//生成相应的getter、setter方法 } 修改配置文件 <class name="xxx.User" table="t_user"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <set name="roles" table="t_user_role"> <key column="userid"/> <many-to-many class="xxx.Role" column="roleid"/> </set> </class> ------------------------------------------------------------------------------------------------ <class name="xxx.Role" table="t_role"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <set name="users" table="t_user_role" order-by="userid"> <key column="roleid"/> <many-to-many class="xxx.User" column="userid"/> </set> </class> 注意点:1、双向多对多关联两边都需要指定连接表的表名和外键列的列名 2、两个集合元素Set的table值必须指定,而且需要相同 七、双向的一对一关联 双向的1-1关联有两种形式: 1、基于外键的双向1-1关联 我们可以回想一下上面提到的单向1-1映射,它是有N-1的一个特例,只需要在<many-to-one>标签多的一端添加unique="true"属性就可以形成单向的1-1映射关系,那么该怎么样将这种映射改为双向的呢? 下面我们再举个例子:一个User必须要有一个唯一的identityId 首先创建两个POJO类 public class Person { private int id; private String name; private IdentityId identityId; ..//生成相应的getter、setter方法 } public class IdentityId { private int id; private String cardNo; private Person person; ..//生成相应的getter、setter方法 } **看配置文件 <class name="xxx.Person" table="t_person"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <many-to-one name="identityId" class="xxx.IdentityId" unique="true"/> </class> ----------------------------------------------------------------------------------- <class name="xxx.IdentityId" table="t_identity"> <id name="id"> <generator class="native"/> </id> <property name="cardNo"/> <one-to-one name="person" class="xxx.Person" property-ref="identityId"/> </class> 注意:这里的property-ref属性为identity表明建立了从identity对象到person对象的关联. 因此只要调用identity持久化对象的getIdentityId()方法就可以导航到Person对象 由此可见: Person对象和IdentityId对象之间为双向的关联关系person.getIdentityId().getPerson() 2、基于主键的1-1双向关联 上面的POJO类不需要有任何变化,我们只需要修改配置文件 <class name="xxx.Person" table="t_person"> <id name="id" column="ID"> <generator class="foreign"> <param name="property">identityId</param> </generator> </id> <property name="name"/> <one-to-one name="identity" clsss="xxx.IdentityId" constrained="true"/> </class> 注意:这里的constrained="true"表明Person表的主键ID同时作为外键参考IdentityId表 -------------------------------------------------------------------------------------- <class name="xxx.Identity" table="t_identity"> <id name="id"> <generator class="native"/> </id> <property name="cardNo"/> <one-to-one name="person" class="xxx.Person"/> </class> 注意:这里Person表中ID既是主键同时还作为外键参照表IdentityId,因为使用了foreign标识符生成策略Hibernate就保证了Person 对象与关联的IdentityId对象共享一个主键


这个双向单向是面向对象的说法 意思就是你更新一个表另外一个表里面关联的数据跟着改变
双向就是这两个表无论哪一个更新另外一个表都更新  单向就是只有一个主表(顾客表)更新从表(商品表)才更新 从表更新主表不管

双向可以两端都直接关联对方,比如学生和老师,处理成双向,可以查学生时也查出老师是谁,查老师时也查出有哪些学生。
单向用在某一端不需要关联查对方的时候,比如学校和学生,查学校时一般不会需要关联把所有学生都查出来的吧?这样太费性能了,也没实用性。于是就设为单向,学生关联学校,简化了维护关系。
需要通过学校查学生时再另写查询语句好了。

posted on 2012-03-24 20:50  lovebeauty  阅读(391)  评论(0编辑  收藏  举报

导航