Hibernate映射(二)——多对一关系映射

  上篇学习了Hibernate的基本映射,也就是单表映射,很容易就能理解,但是对于关系数据库来说,表之间存在关系是比不可少的,关系数据库中存在的关系是通过主外键建立起来的,反应到Hibernate要如何通过对象表现呢?下面我们就继续学习Hibernate的对象关系映射。

  我们先从最常见的多对一和一对多关系开始:

多对一

  所谓多对一,在数据库中即在多的一端添加外键关联到一的一端,比如用户(User)和用户所在组(Group)的关系:一个User只属于一个Group,一个Group有多个Group,并且可以通过User获取所在的Group。通过下面的类图和表关系来看Hibernate的映射实现:

1、首先是实体类User和Group

	package tgb.hibernate;

	/*
	 * 用户组
	 */
	public class Group {

		private int id;
		private String name;

		public int getId() {
			return id;
		}
		public void setId(int id) {
			this.id = id;
		}

		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
	}
	package tgb.hibernate;

	/**
	 * 用户
	 * @author Jones
	 *
	 */
	public class User {

		private int id;
		private String name;

		//关联用户组属性(在用户实体中添加用户组,表明通过用户可以看到所在组)
		private Group group;

		public int getId() {
			return id;
		}
		public void setId(int id) {
			this.id = id;
		}

		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}

		public Group getGroup() {
			return group;
		}
		public void setGroup(Group group) {
			this.group = group;
		}
	}

我们在多的一端(User)添加Group的属性引用,这样可以通过User对象得到Group对象。

2、映射文件配置

用户组Group.hbm.xml

	<hibernate-mapping>
		<class name="tgb.hibernate.Group" table="t_group">
			<id name="id">
				<generator class="native"/>
			</id>
			<property name="name"/>
		</class>
	</hibernate-mapping>

用户User.hbm.xml

	<hibernate-mapping>
		<class name="tgb.hibernate.User" table="t_user">
			<id name="id">
				<generator class="native"/>
			</id>
			<property name="name"/>
			<many-to-one name="group" column="groupid" cascade="save-update"/>
		</class>
	</hibernate-mapping>

通过配置文件我们看到,多对一关系映射的实现是:

在多的一端(User)采用如下标签映射:

<many-to-onename="group" column="groupid"/>

  映射成功后,后续就是对对象的操作(增删改查-持久化到数据库),用了以上映射,我们可以通过Hibernate的级联操作对实体进行快捷操作。但是这样还不够,这里就来看级联操作的问题。例如我们需要添加用户组和组下的用户:

级联问题:

session = HibernateUtils.getSession();
session.beginTransaction();

Group group = new Group();
group.setName("系统管理员");

User user1 = new User();
user1.setName("张三");
user1.setGroup(group);

User user2 = new User();
user2.setName("李四");
user2.setGroup(group);

session.save(user1);
session.save(user2);

//在清理缓存是发生错误TransientObjectException
//因为Group为Transient状态,没有被session,在数据库中没有匹配的数据
//而User为Persistent状态,在清理缓存时hibernate在缓存中无法找到Group对象
//结论:Persistent状态的对象不能引用Transient状态的对象
session.getTransaction().commit();

  正如注释所说会发生TransientObjectException错误,在保存对象(user)过程中,该对象有一个属性(外键)关联的另外一个未持久化的对象(未保存的对象group),解决方法是先保存"被关联"的那个对象,才能保存先前的那个对象,当然我们这样可以实现我们的需要,但是Hibernate提供了更快捷的方式,下面看Hibernate的级联操作和配置。

级联操作

  级联是对象之间的连锁操作,它只影响添加、删除和修改。Hibernate对级联的控制是在配置文件的关系标签中通过cascade进行配置。

还以添加用户组和用户为例,我们需要对<many-to-one>中添加:

<many-to-one name="group" column="groupid" cascade="save-update"/>

“cascade”就来说明在操作两个或多个关联对象,当对其中一个对象进行某种操作时,是否对其关联的对象也作类似的操作。比如我们保存用户是是否也同时保存其所在组。

级联(Cascade)还有如下常用属性:

    (1)none:在保存,删除或修改当前对象时,不对其附属对象(关联对象)进行级联操作。它是默认值。

    (2)save-update:在保存,更新当前对象时,级联保存,更新附属对象(临时对象,游离对象)。

    (3)delete:在删除当前对象时,级联删除附属对象。

    (4)all:所有情况下均进行级联操作,即包含save-update和delete等等操作。

    (5)delete-orphan:删除此对象的同时删除与当前对象解除关系的孤儿对象(仅仅使用于一对多关联关系中)。

    这些我们可以根据具体的业务进行设置。

总结

   Hibernate中的关系映射反应的就是类之间的关系,关系数据库中就是主外键关系,数据库和UML我们都很熟了,映射也就没有问题,当然关系映射在Hibernate是最基础的内容了,项目实践是必不可少了。下文继续Hibernate的一对多映射(包括双向映射)。

时间: 2024-10-11 16:11:04

Hibernate映射(二)——多对一关系映射的相关文章

深入浅出Hibernate(二)多对一关系映射

学习Hibernate是为了更方便的操作数据库,在数据库中的关系模型中存在多对一的关系,比如下图所示的员工和部门之间的关系,那么这种关系在Hibernate中如何映射呢?让我用一个小Demo来详细讲解. 建立映射分为以下几步: 1.设计domain对象Department.Employee,代码如下: package cn.itcast.hibernate.domain; public class Department { private int id; private String name;

Hibernate学习笔记(五) — 多对多关系映射

多对多关系映射 多对多建立关系相当于在第三张表中插入一行数据 多对多解除关系相当于在第三张表中删除一行数据 多对多修改关系相当于在第三张表中先删除后增加 多对多谁维护效率都一样.看需求 在实际开发过程中,多对多的映射关系比较常见. 学生选课示例,一个学生可以选多门课,一门课也可以由多个学生去选,这样就形成了多对多的映射关系 public class Student implements Serializable { private static final long serialVersionU

Hibernate多对多关系映射(建表)

下边讲述Hibernate多对多关系映射. 多对多关系的表的结构为: 两个实体表,还包含一个关系表,关系表为复合主键,如果要使用Hibernate多对多关系映射,则关系表必须只包含两个字段,如果生成了Hibernate多对多关系映射,则中间关系表不会生成实体(即没有对应的pojo类,更没有其映射文件). 1.建立表 DROP TABLE user_course ; DROP TABLE user ; DROP TABLE course ; CREATE TABLE user ( userid  

Hibernate自身一对多和多对多关系映射

一对多关系映射大家都明白,关系双方都一个含有对方多个引用,但自身一对多很多同学都不明白什么意思,那么首先我就说明一下什么是自身一对多,其实也很好理解,自身一对多就是自身含有本身的多个引用,例如新闻类别,新闻包含体育新闻和政治新闻,体育新闻内有含有足球新闻和篮球新闻,其实他们都属于新闻,只是名字不同而已,下面我们就以新闻类别为例来具体说明一下: 首先我们来看一下新闻类别的类图: 类图:category 从上面的图我们可以看出:每一个新闻类别都有一个父类别和一个孩子类别的set集合,这个父类别和孩子

【Java EE 学习第46天】【Hibernate学习第三天】【多对多关系映射】

一.多对多关系概述 以学生和课程之间的关系为例. 1.在多对多关系中涉及到的表有三张,两张实体表,一张专门用于维护关系的表. 2.多对多关系中两个实体类中应当分别添加对方的Set集合的属性,并提供set和get方法. 3.在配置映射文件的时候较一对多关系复杂. 二.映射文件 <set name="students" table="course_stu" cascade="save-update" inverse="true&quo

Hibernate ManyToOne Mappings 多对一关联映射

Hibernate框架的使用步骤: 1.创建Hibernate的配置文件(hibernate.cfg.xml) 2.创建持久化类,即其实例需要保存到数据库中的类(Employee.java) 3.创建对象-关系映射文件(Employee.hbm.xml) 4.通过Hibernate API编写访问数据库的代码 例子:多个员工对应一个地址. 一.创建hibernate.cfg.xml 配置文件: 注意数据库名.用户名.密码是否填写正确. <?xml version="1.0" en

Hibernate(三)——框架中的关系映射

在设计数据库时我们会考虑,表与表之间的关系,例如我们前边经常提到的一对一,一对多,多对多关系,在数据库中我们通过外键,第三张表等来实现这些关系.而Hibernate时间实体类和数据库中的表进行的映射,这些关系如何映射呢?这里简单总结一下: 一,一对多,多对一关系映射,这里拿学生和班级进行简单演示: 1,学生的类和对应的映射文件的编写: private int sid ; private String sname ; private Classes classes ; //,引入班级对象,多对一

Hibernate之配置文件以及对象关系映射文件了解

声明:CSDN不知道怎么了,有时候就是发表不了博文.本来就是一天一篇博文,最近搞的我很郁闷.有时候一天,有时候两三天都不能发.这就属于不可抗力.没办法的,啥时能发,我就发了. 一.学习案例:关于hibernate的配置文件以及对象关系映射文件的了解. 二.案例分析: a)hibernate配置文件(hibernate.cfg.xml) 1.hibernate.dialect:数据库使用的SQL方言 2.hiebrnate.connection.driver_class:数据库的驱动程序 3.hi

Hibernate One-to-Many Mappings 一对多关系映射

Hibernate One-to-Many Mappings 一对多关系映射 关键点:一对多关系使用 Set 实现, 例子:一个员工可以有多个学证书. Hibernate框架的使用步骤: 1.创建Hibernate的配置文件(hibernate.cfg.xml) 2.创建持久化类,即其实例需要保存到数据库中的类(Employee.java) 3.创建对象-关系映射文件(Employee.hbm.xml) 4.通过Hibernate API编写访问数据库的代码 创建Hibernate的配置文件(h