接触Hibernate也有一小段的时间了,愈发的觉得Hibernate是个神奇的东西,为什么这么说呢?因为你可以不懂一行sql,直接面向对象,就可以将数据直接保存到数据库去!!

你还可以保存一个对象,然后一次性的将与它相关的所有数据保存到数据库,比如说,你只需要保存班级对象,就可以将该班级信息和该班级下的所有学生在数据库中形成一堆的记录。

而且都不需要你写sql!!!

有木有很神奇。。。。反正宝宝我是惊呆了。

下面就拿具体的代码实现来讲吧~

首先讲一个简单的  单向一对多的案例(以班级和学生作为案例)

众所周知,Hibernate运用的是一种面向对象的思想,我们想要与数据库相关联,首先我们得必须有与之相对应的实体类

比如说,我有一个学生对象和班级对象,分别对应数据库中的学生表和班级表具体信息如下:

package entity;
/*
*学生表 
*/
import java.io.Serializable; public class Student implements Serializable {
private Integer sid;//学生编号
private String sname;//学生姓名
private String sex;//学生性别 public Student() {
} public Student(String sname, String sex) {
this.sname = sname;
this.sex = sex;
} public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
} }
package entity;
/*
*班级表
*/
import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Set; public class Grade implements Serializable {
private Integer gid;//班级编号
private String gname;//班级名称
private String gdesc;//班级描述 public Grade() {
} public Grade(String gname, String gdesc) {
this.gname = gname;
this.gdesc = gdesc;
} public Integer getGid() {
return gid;
}
public void setGid(Integer gid) {
this.gid = gid;
}
public String getGname() {
return gname;
}
public void setGname(String gname) {
this.gname = gname;
}
public String getGdesc() {
return gdesc;
}
public void setGdesc(String gdesc) {
this.gdesc = gdesc;
} }

一对多的话,应该是比较好理解的,因为我们可以理解为   一个班级可以以对应多个学生,这就是一对多,既然一个班级对应多个学生的话,那么我们是不是就可以在班级的实体类

中加入一个学生集合和呢?这样是不是更能体现出一对多的关系呢?所以我们对班级实体就有了下面的改造

package entity;

import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Set; public class Grade implements Serializable {
private Integer gid;//年级编号
private String gname;//年级名称
private String gdesc;//年级描述
//添加一个班级里的学生集合
private Set<Student> stus=new HashSet<Student>(); public Set<Student> getStus() {
return stus;
} public void setStus(Set<Student> stus) {
this.stus = stus;
} public Grade() {
} public Grade(String gname, String gdesc) {
this.gname = gname;
this.gdesc = gdesc;
} public Integer getGid() {
return gid;
}
public void setGid(Integer gid) {
this.gid = gid;
}
public String getGname() {
return gname;
}
public void setGname(String gname) {
this.gname = gname;
}
public String getGdesc() {
return gdesc;
}
public void setGdesc(String gdesc) {
this.gdesc = gdesc;
} }

实体类写完了,我们就该写最关键的配置文件也就是映射文件了(Grade.hbm.xml)

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- 对应所在的包 -->
<hibernate-mapping package="entity">
<!-- 实体类和数据表的名称 -->
<class name="Grade" table="Grade">
<!-- 实体类中和数据表中所对应的主键 -->
<id name="gid" column="gid">
<!-- 主键生成策略 increment是值找到最大的主键 值,并加1 -->
<generator class="increment" />
</id>
<!-- 非主键属性的配置 -->
<property name="gname" column="gname" />
<property name="gdesc" column="gdesc"/> <!-- 配置多对一配置信息 -->
<set name="stus" table="Student" >
<!-- 多方的外建值 -->
<key column="gid"></key>
<one-to-many class="entity.Student"/>
</set>
</class>
</hibernate-mapping>

这样我们就完成了一对多的配置了,此时,我们不用对Student.hbm.xml做任何操作,下面可以测试了

//单向一对多案例(一个班级对应多个学生)
public static void DOneToManyAdd(){
//准备session
Session session=HibernateUtil.currentSession();
//开启事务
Transaction tx = session.beginTransaction();
//创建一个班级
Grade grade=new Grade("S1261","无敌的Y1261班");
//准备几个学生
Student stu1=new Student("微热的雪","女");
Student stu2=new Student("巴黎的雨季","男");
//设置班级里的学生
grade.getStus().add(stu1);
grade.getStus().add(stu2); //保存
session.save(grade);
session.save(stu1);
session.save(stu2); //提交事务
tx.commit();
//关闭连接
HibernateUtil.closeSession();
}

执行这些代码后可以在控制台看到如下信息

这个时候,你的数据库中便有了如下信息

可以从上面的测试代码中看出,我并没有手动的指定学生所在的班级,但是因为有映射文件,Hibernate会自动的检索到所在的班级并自行的发送sql语句到数据库进行持久化操作。

这就是Hibernate的强大之处,当然,这只是一个最简单的例子,下面就跟着我看看更加有趣的例子吧!

Hibernate关系映射二之   单向多对一关系映射

多对一关系映射也同样的好理解,比如,多个学生可以同时处于一个班级下,这就是单向的多对一的关系,所以我们就可以想到在学生表中加入一个班级属性

package entity;

import java.io.Serializable;

public class Student implements Serializable {
private Integer sid;//学生编号
private String sname;//学生姓名
private String sex;//学生性别
//创建一个班级
private Grade grade; public Grade getGrade() {
return grade;
} public void setGrade(Grade grade) {
this.grade = grade;
} public Student() {
} public Student(String sname, String sex) {
this.sname = sname;
this.sex = sex;
} public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
} }

因为是单向的多对一,所以我们只需要在多的一方,也就是学生方的配置文件中进行修改,班级方的配置文件保持原始(也就是没有set标签的时候)

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="entity">
<class name="Student" table="Student">
<id name="sid" column="sid">
<generator class="increment" />
</id>
<property name="sname" column="sname" />
<property name="sex" column="sex"/>
<!-- 配置多对一的关系映射 -->
<many-to-one name="grade" class="entity.Grade" column="gid"></many-to-one>
</class>
</hibernate-mapping>

同样,我们做一个单向多对一的添加操作

//单向多对一添加案例(多个学生对应一个班级)
public static void DManyToOneAdd(){
//准备session
Session session=HibernateUtil.currentSession();
//开启事务
Transaction tx = session.beginTransaction();
//创建一个班级
Grade grade=new Grade("S2222班","挺6的S2222班");
//准备几个学生
Student stu1=new Student("恩恩","男");
Student stu2=new Student("呵呵","女");
//设置学生所在的班级
stu1.setGrade(grade);
stu2.setGrade(grade);
//保存
session.save(grade);
session.save(stu1);
session.save(stu2);
//提交事务
tx.commit();
//关闭连接
HibernateUtil.closeSession();
}

注意!!!此时的Hibernate生成的sql语句与一对多时是不一样的!

数据库中同样也是有相对应的记录

经过上面两个案例的展示,可能有同学就会有疑问了,既然多个学生可以属于一个班级,一个班级又可以有多个学生,那么他们俩之间到底可以设为 什么关系呢?

此时,我们就可以设置为  双向的一对多的关系了。因为班级和学生是一个双向的关系,而且一个班级又有多个学生

这时我们完整的配置文件就是以上的两个总和了

Student.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="entity">
<class name="Student" table="Student">
<id name="sid" column="sid">
<generator class="increment" />
</id>
<property name="sname" column="sname" />
<property name="sex" column="sex"/>
<!-- 配置多对一的关系映射 -->
<many-to-one name="grade" class="entity.Grade" column="gid" ></many-to-one>
</class>
</hibernate-mapping>

Grade.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- 对应所在的包 -->
<hibernate-mapping package="entity">
<!-- 实体类和数据表的名称 -->
<class name="Grade" table="Grade">
<!-- 实体类中和数据表中所对应的主键 -->
<id name="gid" column="gid">
<!-- 主键生成策略 increment是值找到最大的主键 值,并加1 -->
<generator class="increment" />
</id>
<!-- 非主键属性的配置 -->
<property name="gname" column="gname" />
<property name="gdesc" column="gdesc"/> <!-- 配置多对一配置信息 -->
<set name="stus" table="Student" >
<!-- 多方的外建值 -->
<key column="gid"></key>
<one-to-many class="entity.Student"/>
</set>
</class>
</hibernate-mapping>

测试数据

//双向添加案例
private static void SAdd(){
//准备session
Session session=HibernateUtil.currentSession();
//开启事务
Transaction tx = session.beginTransaction();
//创建一个班级
Grade grade=new Grade("S2222班","挺6的S2222班");
//准备几个学生
Student stu1=new Student("巴黎的雨季","男");
Student stu2=new Student("微热的雪","女");
//设置班级下的学生
grade.getStus().add(stu1);
grade.getStus().add(stu2);
//为学生设置班级
stu1.setGrade(grade);
stu2.setGrade(grade);
//保存
session.save(grade);
session.save(stu1);
session.save(stu2);
//提交事务
tx.commit(); //关闭连接
HibernateUtil.closeSession();
}

细心的同学会发现,当我执行了上面的代码时,效果与我设置多对一和一对多的效果一样,而且这还比较的繁琐和复杂,所以这并不是双向关系的优势

这里我们就要用到cascade(级联)的属性了   设置级联的属性后,因为有 双向的关系,所以当你只添加班级的时候Hibernate会自动的添加班级下的学生

Student.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="entity">
<class name="Student" table="Student">
<id name="sid" column="sid">
<generator class="increment" />
</id>
<property name="sname" column="sname" />
<property name="sex" column="sex"/>
<!-- 配置多对一的关系映射 -->
<many-to-one name="grade" class="entity.Grade" column="gid" cascade="all"></many-to-one>
</class>
</hibernate-mapping>

Grade.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- 对应所在的包 -->
<hibernate-mapping package="entity">
<!-- 实体类和数据表的名称 -->
<class name="Grade" table="Grade">
<!-- 实体类中和数据表中所对应的主键 -->
<id name="gid" column="gid">
<!-- 主键生成策略 increment是值找到最大的主键 值,并加1 -->
<generator class="increment" />
</id>
<!-- 非主键属性的配置 -->
<property name="gname" column="gname" />
<property name="gdesc" column="gdesc"/> <!-- 配置多对一配置信息 -->
<set name="stus" table="Student" cascade="all" inverse="true">
<!-- 多方的外建值 -->
<key column="gid"></key>
<one-to-many class="entity.Student"/>
</set>
</class>
</hibernate-mapping>

这样当我们设置级联的属性后,测试代码如下

//双向添加案例(添加班级自动添加班级下的学生)
private static void SAdd(){
//准备session
Session session=HibernateUtil.currentSession();
//开启事务
Transaction tx = session.beginTransaction();
//创建一个班级
Grade grade=new Grade("S2222班","挺6的S2222班");
//准备几个学生
Student stu1=new Student("巴黎的雨季","男");
Student stu2=new Student("微热的雪","女");
//设置班级下的学生
grade.getStus().add(stu1);
grade.getStus().add(stu2);
//为学生设置班级
stu1.setGrade(grade);
stu2.setGrade(grade);
//保存(设置级联属性,自动关联该班级下的学生)
session.save(grade); //提交事务
tx.commit(); //关闭连接
HibernateUtil.closeSession();
}

这样,我们只用写save(grade) 保存班级,这时Hibernate会生成如下代码

至此,基本上就讲完了Hibernate中单向关系映射的知识点了,明天为大家讲解关于双向多对多关系映射的知识点。

详谈Hibernate框架关系映射!的更多相关文章

  1. Hibernate框架关系映射一对多双向关联

    直入主题,首先大配置常规配置, 这里住要说关联关系,大配置不多少,而且jar包默认添加好,笔者用的是idea2016. 然后我们知道关联关系主要是在小配置添加节点来配置属性.个人认为关联映射,就是对应 ...

  2. hibernate(3) —— 关系映射

    hibernate中关系映射指的是实体类与实体类间的关系.和数据库中表与表之间的关系类似,有一对一,多对一,一对多,多对多四种映射关系. 一:一对一映射 两个对象之间是一对一的关系,如人和身份证之间是 ...

  3. Hibernate注解关系映射

    Hibernate Annotation关系映射的几种类型映射用法及使用方法(说明:以前实例的实体是user和role,主键分别是userid和roleid)   1)一对一外键关联映射(单向) @O ...

  4. hibernate 实体关系映射笔记

    @经常使用属性说明:     @Entity:实体类     @Table:指定相应数据表     @Id:主键,使用能够为null值的类型,假设实体类没有保存到数据库是一个暂时状态     @Col ...

  5. hibernate对象关系映射( 一对一,一对多,多对一,多对多的单向,双向映射 ——)

    对象之间的关系: 关系映射之间的关系只的是对象之间的关系,并不指数据库表的关系(外键关系)这儿解决的问题是当对象之间的关系之一时,数据库表该如何映射,编程上如何对待. 一对一(主键关联,和单向的外键关 ...

  6. Hibernate 对象关系映射文件

    简介: POJO 类和关系型数据库之间的映射可以用一个 XML 文档来定义 通过 POJO 类的数据库映射文件,Hibernate 可以理解持久化类和数据表之间的对应关系,也可以理解持久化类属性与数据 ...

  7. Hibernate表关系映射之一对一映射

    一.数据表的映射关系 在数据库领域中,数据表和数据表之间关系一般可以分为如下几种: 一对一:比如公民和身份证的关系,一个人只有一张身份证,同时每张身份证也仅仅对应一个人! 一对多:比如客户和订单之间的 ...

  8. MyBatis框架——关系映射(一对多、多对多、多对一查询)

    关系映射 一.映射(多)对一.(一)对一的关联关系 1).使用列的别名 ①.若不关联数据表,则可以得到关联对象的id属性 ②.若还希望得到关联对象的其它属性.则必须关联其它的数据表 1.创建表: 员工 ...

  9. Hibernate实体关系映射(OneToMany单边)——完整实例

    单边一对多关系:电子邮件管理 单边一对多关系:指一方有集合属性,包含多个多方,而多的一方没有一方的引用. 比如:用户(一)与电子邮件(多).一个用户可以有多个电子邮件记录. 目的:通过OneToMan ...

随机推荐

  1. Windows Azure Virtual Machine (25) 使用SSH登录Azure Linux虚拟机

    <Windows Azure Platform 系列文章目录> 本文介绍内容适合于Azure Global和Azure China 为什么使用SSH登录Azure Linux虚拟机? 我们 ...

  2. IT传统组织结构及新型扁平化组织

    如今互联网企业正凶猛的改变人们衣食住行的方方面面,衣->淘宝,蘑菇街;食->大众点评,口碑;住->去哪,途牛:行->12306, 多次听到互联网的同行介绍他们就是要“快”,快速 ...

  3. Android中viewPager的一两点使用

    Android中viewPager的一两点使用 viewPager是谷歌官方提供的一种方便实现页面滑动效果的控件,可以直接使用也可以和fragment联合使用.这里只简单说下直接使用. 使用viewP ...

  4. osgi 1

    Helloworld入门 准备: eclipse 3.4 需要jar,—— eclipse 自带的,plugin下面有很多,抛开里面的jar,很多都是当前项目不需要的,如果不适用eclipse而是直接 ...

  5. PHPer书单

    想提升自己,还得多看书!多看书!多看书! 下面是我收集到的一些PHP程序员应该看得书单及在线教程,自己也没有全部看完.共勉吧! Github地址:https://github.com/52fhy/ph ...

  6. Atitit usrQBF2312 命名空间pkg 以及 api命名 spec规范

    Atitit usrQBF2312 命名空间pkg 以及 api命名 spec规范 简化英文1 常用类库sdk的命名单词统计表1 简化时间规则1 Namsspace nam spec,参照java . ...

  7. .net生成随机字符串

    生成随机字符串的工具类: /// <summary> /// 随机字符串工具类 /// </summary> public class RandomTools { /// &l ...

  8. XML学习笔记5——XSD复杂数据类型

    和简单数据类型对应就是复杂数据类型了,XML元素的数据类型可以是简单数据类型,也可以是复杂数据类型,而XML属性的数据类型就只能是简单数据类型.这篇笔记,就来学习一下XSD中的复杂数据类型了. 1.定 ...

  9. binary 和 varbinary 用法

    数据类型 binary(n) 和 varbinary(n) 用于存储二进制数据,n是指字节数量: binary( n ):长度为 n 字节的固定长度二进制数据,其中 n 是从 1 到 8,000 的值 ...

  10. JS中的匿名函数

    整理自:http://www.cnblogs.com/playerlife/archive/2012/10/17/2727683.html 一.什么是匿名函数? 在Javascript定义一个函数一般 ...