在hibernate中非常重要的就是映射,在前面的博文中,小编简单的介绍了基本映射,基本映射是对一个实体进行映射,关联映射就是处理多个实体之间的关系,将关联关系映射到数据库中,所谓的关联关系在对象模型中有一个或多个引用。这个比较简单,但是基础知识还是需要好好掌握的哦,还有一些关联映射,比如user && group,她们之间的关系是一对多,我们知道一个用户只能属于一个组,但是一个组可以包好N多个用户,所以他们之间的关系就是多对一的关系,接着我们来看他们的对象模型以及关系模式。

所谓多对一单向关联映射,就是 多的一端维护关联关系,在“多”的一端加入一个外键,指向“一”的一端。多的一端持有一的一端的引用,即在“多”的一端加外键,指向“一”的一端。ok,接着我们来看User and Group的对象模型以及关系模式模型,首先对象模型:


       接着关系模型如下所示:

接着,小编用代码来实现相应的原理,还请小伙伴们多多指教哦。

第一步、建立User和Group两个实体类,并且编写代码,首先是User类,代码如下所示:

package com.bjpowernode.hibernate;

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;
	}

}

接着编写Group的代码,如下所示:

package com.bjpowernode.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;
	}

}

第二步、我们要从用户看到组,所以要关联,so,需要在User里面添加Group代码,编写映射文件User.hbm.xml 和Group.hbm.xml。首先User.hbm.xml,代码如下所示:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.bjpowernode.hibernate.User" table="t_user">
    	<id name="id">
    		<generator class="native"/>
    	</id>
    	<properties name="name"/>
    	<many-to-one name="group" column="groupid" cascade="save-update"/>
    </class>
</hibernate-mapping>

接着编写Group.hbm.xml,代码如下所示:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.bjpowernode.hibernate.Group" table="t_group">
    	<id name="id">
    		<generator class="native"/>
    	</id>
    		<property name="name"/>
    </class>
</hibernate-mapping>

第三步、编写Hibernate.cfg.xml映射文件里面的内容,代码如下所示:

<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory >
		<!-- MySql数据库驱动 -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<!-- 数据库名称 -->
		<property name="hibernate.connection.url"> jdbc:mysql:///hibernate_many2one</property>
		<!-- 数据库的用户名 -->
		<property name="hibernate.connection.username">root</property>
		<!-- 数据库的密码 -->
		<property name="hibernate.connection.password">123456</property>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<!-- 显示语句 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 格式排版 -->
        <!-- <property name="hibernate.format_sql">true</property> -->    

		<mapping resource="com/bjpowernode/hibernate/User.hbm.xml"/>
		<mapping resource="com/bjpowernode/hibernate/Group.hbm.xml"/>
	</session-factory>
</hibernate-configuration>

第四步、创建数据库,并且运行ExportDB文件,我们来看一下数据库里面的信息,效果如下所示:


       关联映射已经搞定,接下来向里面添加数据,看看关联如何发挥作用。
       第五步、建立Many2oneTest,编写第一个方法,如下所示:

package com.bjpowernode.hibernate;

import org.hibernate.Session;

import junit.framework.TestCase;

public class Many2oneTest extends TestCase {

	public void testSave1(){

		Session session = null;
		try{
			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);

			session.getTransaction().commit();

		}catch(Exception e){
			e.printStackTrace();
			session.getTransaction().rollback();

		}finally{
			HibernateUtils.closeSession(session);

		}
	}
}

运行这个方法,我们发现,在清理缓存的时候发生错误TransientObjectException,因为Group为Transient状态,没有被session,在数据库中没有匹配的数据,而User为persistent状态,在清理缓存时Hibernate在缓存中无法找到Group,so--Persistent状态的对象不能引用Transistent状态的对象,ok,接着,我们来改进一下相关代码如下所示:

public void testSave2() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();

			Group group = new Group();
			group.setName("动力节点");
			session.save(group);

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

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

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

			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}	

运行,发现现在可以可以正确的保存数据,因为Group和User都是Persistent状态的对象所以在hibernate清理缓存时在session中可以找到关联对象。接着再编写一个方法,介绍一个属性,这个属性叫做级联,级联就是一些连锁性的操作,级联的意思是指定两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作。比如保存某个用户的时候,可以级联把别人保存了。首先,修改User.hbm.xml文件的代码,如下所示:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.bjpowernode.hibernate.User" table="t_user">
    	<id name="id">
    		<generator class="native"/>
    	</id>
    	<properties name="name"/>
    	<many-to-one name="group" column="groupid" cascade="save-update"/>
    </class>
</hibernate-mapping>

方法编写,如下所示:

	public void testSave3() {
		Session session = null;
		try {
			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异常
			//因为使用了级联特性
			//hibernate会首先保存User的关联对象对象Group
			//Group和User就都是Persistent状态的对象了
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}	

执行这个方法,ok,运行,如下所示:


        小编寄语:该博文,小编主要简单的介绍了hibernate中的多对一单向关联映射,项目中,多对一关联映射是最常见的映射,但它是Hibernate的关联映射中最简单的一种映射关系。学习就是这样,点点滴滴的积累,下篇博文,小编将继续介绍hibernate的相关知识,敬请期待`(*∩_∩*)′!

【SSH系列】Hibernate映射-- 多对一单向关联映射的更多相关文章

  1. 【SSH进阶之路】Hibernate映射——多对一单向关联映射(四)

    [SSH进阶之路]Hibernate基本原理(一) ,小编介绍了Hibernate的基本原理以及它的核心,採用对象化的思维操作关系型数据库. [SSH进阶之路]Hibernate搭建开发环境+简单实例 ...

  2. (Hibernate进阶)Hibernate映射——多对一单向关联映射(四)

    介绍基于基本映射的关联关系映射. 概念 基本映射是对一个实体进行映射,关联映射就是处理多个实体之间的关系,将关联关系映射到数据库中,所谓的关联关系在对象模型中有一个或多个引用. 分类 关联关系分为上述 ...

  3. Hibernate从入门到精通(七)多对一单向关联映射

    上次的博文Hibernate从入门到精通(六)一对一双向关联映射中我们介绍了一下一对一双向关联映射,本次博文我们讲解一下多对一关联映射 多对一单向关联映射 多对一关联映射与一对一关联映射类似,只是在多 ...

  4. Hibernate(七)多对一单向关联映射

    上次的博文Hibernate从入门到精通(六)一对一双向关联映射中我们介绍了一下一对一双向关联映射,本 次博文我们讲解一下多对一关联映射 多对一单向关联映射 多对一关联映射与一对一关联映射类 似,只是 ...

  5. [置顶] Hibernate从入门到精通(七)多对一单向关联映射

    上次的博文Hibernate从入门到精通(六)一对一双向关联映射中我们介绍了一下一对一双向关联映射,本次博文我们讲解一下多对一关联映射 多对一单向关联映射 多对一关联映射与一对一关联映射类似,只是在多 ...

  6. Hibernate从入门到精通(十)多对多单向关联映射

    上一篇文章Hibernate从入门到精通(九)一对多双向关联映射中我们讲解了一下关于一对多关联映射的相关内容,这次我们继续多对多单向关联映射. 多对多单向关联映射 在讲解多对多单向关联映射之前,首先看 ...

  7. Hibernate(十)多对多单向关联映射

    上一篇文章Hibernate从入门到精通(九)一对多双向关联映射中我们讲解了一下关于一对多关联映射的 相关内容,这次我们继续多对多单向关联映射. 多对多单向关联映射 在讲解多对多单向关联映 射之前,首 ...

  8. [置顶] Hibernate从入门到精通(十)多对多单向关联映射

    上一篇文章Hibernate从入门到精通(九)一对多双向关联映射中我们讲解了一下关于一对多关联映射的相关内容,这次我们继续多对多单向关联映射. 多对多单向关联映射 在讲解多对多单向关联映射之前,首先看 ...

  9. Hibernate之关于多对多单向关联映射

    [Hibernate]之关于多对多单向关联映射 老师和学生,最典型的多对多关联, Teacher和Student.所谓单向意思就是说.老师知道自己的教的是哪些学生而学生不知道是哪些老师教. 也能够这么 ...

随机推荐

  1. 洛谷 P3038 [USACO11DEC]牧草种植Grass Planting(树链剖分)

    题解:仍然是无脑树剖,要注意一下边权,然而这种没有初始边权的题目其实和点权也没什么区别了 代码如下: #include<cstdio> #include<vector> #in ...

  2. 解决firefox不支持-webkit-line-clamp属性

    转载声明: 请注明本文引用自http://www.cnblogs.com/guolizhi/ css中-webkit-line-clamp这个属性表示超过指定行的文本隐藏并且会在结尾加上...号,用起 ...

  3. Java 异常基础详解

    目录 1. Java 中的异常 1.1 什么是异常? 1.2 什么是异常处理? 1.2.1 异常处理的优势 1.3 Java 异常类的层次结构 1.4 异常类型 1.5 检查和未检查异常之间的区别 1 ...

  4. [LeetCode] Design Compressed String Iterator 设计压缩字符串的迭代器

    Design and implement a data structure for a compressed string iterator. It should support the follow ...

  5. k8s踩坑记 - kubeadm join 之 token 失效

    抛砖引玉 环境 centos 7 amd64 两台 kubernetes 1.10 伴随着k8s1.10版本的发布,前天先在一台机器上搭建了k8s单机版集群,即既是master,也是node,按照经验 ...

  6. HTML5 AJAX跨域请求

    HTML5新的标准中,增加了" Cross-Origin Resource Sharing"特性,这个特性的出现使得跨域通信只需通过配置http协议头来即可解决. Cross-Or ...

  7. 参考用bat文件

    @echo off rem *************** start of 'main' set DEBUG= " (set TRACE=echo) else (set TRACE=rem ...

  8. Mac 下安装 MySQL 经历

    1.使用 homebrew 安装: brew install mysql 结果报错: $ brew install mysql ==> Downloading http://dev.mysql. ...

  9. python学习记录 - python3.x中如何实现print不换行

    python3.x中如何实现print不换行   大家应该知道python中print之后是默认换行的, 那如何我们不想换行,且不想讲输出内容用一个print函数输出时,就需要改变print默认换行的 ...

  10. Java的递归、IO流

    .t1 { background-color: #ff8080; width: 1100px; height: 40px } 一.递归 [递归] 1. 在函数自身内部,调用函数本身的方式,称为递归. ...