一、单向的多对一
多对一的关系和关系型数据库中外键参照关系最匹配,在多方表中有一个外键,指向一方表的主键。
单向的多对一映射是我在项目中使用最多的一种配置。
实现:单向的多对一映射关系实现是由多方来维护的。在多方持有一方的引用,在多方的映射文件中配置<many-to-one>属性。
还以之前的学生和班级为基础来看一下具体实现:
说明一下:和单向的一对多一样,单向的多对一也只能通过多来导航到一,是单向的,可以通过学生来导航到班级进行相应的操作,并不能通过班级来导航到学生。
1.持久化类
Grade:
private int gid;
private String gname;
private String gdesc;
Students:需要注意,在Students持久化类中添加了对Grade的引用,并且提供了set/get
private int sid;
private String sname;
private Grade grade;
public Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
2.映射文件
在多方维护,所以Grade.hbm.xml并没有特别之处。
<hibernate-mapping>
<class name="com.iteye.sunyq.hibernate.Grade" table="grade">
<id name="gid" type="integer">
<column name="id"></column>
<generator class="native"></generator>
</id>
<property name="gname" type="string">
<column name="gname"></column>
</property>
<property name="gdesc" >
<column name="gdesc"></column>
</property>
</class>
</hibernate-mapping>
需要在Students.hbm.xml中添加对应外键的映射也就是<many-to-one>
<hibernate-mapping>
<class name="com.iteye.sunyq.hibernate.Students" table="students">
<id name="sid" type="integer">
<column name="id"></column>
<generator class="native"></generator>
</id>
<property name="sname" type="string">
<column name="sname"></column>
</property>
<many-to-one name="grade" class="com.iteye.sunyq.hibernate.Grade">
<column name="gid"></column>
</many-to-one>
</class>
</hibernate-mapping>
通过以上的配置就可以对这两个表进行操作了。
二、双向关联关系
实现:一方为one,一方为many,同时配置<many-to-one>和<set>来建立双向的关联关系。
通过双向的关联关系我们搭建了双向的导航,可以从学生导航到班级,也可以通过班级导航到
学生,只不过性能上需要通过配置来优化一下,下面会说。
还是基于学生和班级来说:
1.持久化类
Grade中保存Students的set集合
...
private int gid;
private String gname;
private String gdesc;
private Set<Students> studentSet = new HashSet<Students>();
...
Students中保存Grade的引用
private int sid;
private String sname;
private Grade grade;
2.映射文件
Grade.hbm.xml中配置Students的外键
<set name="studentSet" inverse="true">
<key column="gid"/><!-- Students表中外鍵名称 -->
<one-to-many class="com.iteye.sunyq.hibernate.Students"></one-to-many><!-- 映射的实体类 -->
</set>
同时需要在Grade.hbm.xml中配置映射关系
<many-to-one name="grade" class="com.iteye.sunyq.hibernate.Grade">
<column name="gid"></column>
</many-to-one>
3.测试类
Session session = HibernateUtil.getSession();
Transaction transaction = session.beginTransaction();
Grade g = new Grade("班级一", "班级一描述");
Students s1 = new Students("学生1");
Students s2 = new Students("学生1");
g.getStudentSet().add(s1);
g.getStudentSet().add(s2);
s1.setGrade(g);
s2.setGrade(g);
session.save(g);
session.save(s1);
session.save(s2);
transaction.commit();
HibernateUtil.closeSession(session);
相应的执行sql如下图:
注意:在这里需要注意一下,因为是双向的关联关系,除了正常的3个insert语句还有2个update更新语句,这是由于Grade中维护一对多关系时产生的。此时为了提高性能,可以在set标签中添加一个设置inverse="true",表明关联关系的维护由多方来维持。
<set name="studentSet" inverse="true">
<key column="gid"/><!-- Students表中外鍵名称 -->
<one-to-many class="com.iteye.sunyq.hibernate.Students"></one-to-many><!-- 映射的实体类 -->
</set>
之后再去测试一下,就没有多余的update语句了:
查询验证:
配置默认的是执行懒加载模式:就是现在学生与班级有多对一的关联关系,但是查询学生的时候不会默认查询相应班级的信息,当使用到班级信息的时候再去执行查询。
Session session = HibernateUtil.getSession();
Transaction transaction = session.beginTransaction();
Students s = (Students) session.get(Students.class, 2);
System.out.println(s.getSname());
transaction.commit();
session.close();
执行的sql:
Session session = HibernateUtil.getSession();
Transaction transaction = session.beginTransaction();
Students s = (Students) session.get(Students.class, 2);
System.out.println(s.getSname());
Grade g =s.getGrade();
System.out.println(g.getGname());
transaction.commit();
session.close();
执行的sql
从结果可以看出来,只有用到相关grade信息时,才去执行的select查询grade表:这个就叫做懒加载。
此时如果想要在获取到students信息的时候就已经获取到全部包含grade的信息时就需要在<many-to-one>中添加一个属性配置
<many-to-one name="grade" class="com.iteye.sunyq.hibernate.Grade" lazy="false">
<column name="gid"></column>
</many-to-one>
此时再次执行上面查询代码:
此时就是全部查询出来的。
这个属性的配置根据需求来定,因为涉及到一定的性能。
- 大小: 35.4 KB
- 大小: 36.6 KB
- 大小: 18.2 KB
- 大小: 28.7 KB
- 大小: 28 KB
分享到:
相关推荐
hibernate 映射关系学习入门 多对多实体映射 源码
hibernate 映射关系学习入门 一对一映射Eclipse源码
包含《多对多双向关联映射》《多对一单向关联映射》《多对一双向关联映射》《一对多单向关联映射》等文档,并有图解及例子,非常适合新手学习,尤其是刚刚接触hibernate,对映射关系不清楚的。。。。
Hibernate映射一对多关联关系
NULL 博文链接:https://1028826685.iteye.com/blog/1536060
1:Hibernate的关联映射,存在一对多和多对一映射,多对多映射: 1.1:一对多和多对一映射,举例说明: 学生和老师: 一个老师可以教多个学生 【一对多映射】 多个学生可以被一个老师教【多对一映射】 部门与员工: ...
hibernate基于 一对多、多对一映射写的一个增加,查询,删除,修改的demo,内附数据库脚本
个人的很详细的Hibernate一对一映射配置详解,对初学者有帮助!
Hibernate一对多,多对一映射
Hibernate一对多映射
hibernate核心,一对多,多对多映射讲解,看了就完全搞明白了
hibernate关联映射详解SSH 多对多,一对多关系对象映射
Hibernate双向一对一关联映射(注解版)
Hibernate映射关系一对多 源代码
Hibernate持久化映射一对多和多对一
hibernate映射枚举类型,hibernate如何映射枚举类型
Hibernate Map 多对多映射
hibernate初学者学习入门之一对多实体映射关系源码
自动生成hibernate映射文件和实体类
使用hibernate技术实现对MySQL数据库的一对多和多对一的映射。下载后对应着改一下自己的IP地址就好了。