接触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. Java基础类型总结

    最近一直在总结反思自己, 趁着现在请假在学校上课的空余时间,从基础开始重新温故学习下Java,充实下自己. 一.数据类型 从下图中,我们可以很清晰的看出Java中的类型,其中红色方框中的是Java的4 ...

  2. Lucene系列-近实时搜索(1)

    近实时搜索(near-real-time)可以搜索IndexWriter还未commit的内容,介于immediate和eventual之间,在数据比较大.更新较频繁的情况下使用.本文主要来介绍下如何 ...

  3. 每天一个linux命令(61):wget命令

    Linux系统​中的wget是一个下载文件的工具,它用在命令行下.对于Linux用户是必不可少的工具,我们经常要下载一些软件或从远程服务器恢复备份到本地服务器.wget支持HTTP,HTTPS和FTP ...

  4. lua的table表处理 及注意事项

    lua,一款很轻量级很nice很强大的脚本语言,做为lua中使用最为频繁的table表,在使用之时还是有颇多的好处与坑的: 下面是大牛 云风的一片关于lua table的blog,可使得对lua ta ...

  5. Atitit oodbms的查询,面向对象的sql查询jpa jpql hql

    Atitit oodbms的查询,面向对象的sql查询jpa jpql hql 1.1. 标准API历史1 1.2. JPA定义了独特的JPQL(Java Persistence Query Lang ...

  6. Atitti 文本分类  以及 垃圾邮件 判断原理 以及贝叶斯算法的应用解决方案

    Atitti 文本分类  以及 垃圾邮件 判断原理 以及贝叶斯算法的应用解决方案 1.1. 七.什么是贝叶斯过滤器?1 1.2. 八.建立历史资料库2 1.3. 十.联合概率的计算3 1.4. 十一. ...

  7. 不要怂,就是GAN (生成式对抗网络) (一)

    前面我们用 TensorFlow 写了简单的 cifar10 分类的代码,得到还不错的结果,下面我们来研究一下生成式对抗网络 GAN,并且用 TensorFlow 代码实现. 自从 Ian Goodf ...

  8. DOM_02之查找及元素操作

    1.查找之按节点间关系查找周围元素: 2.查找之HTML属性:①按id查找:var elem=document.getElementById("id"):找到一个元素,必须docu ...

  9. 常用的java类型转json的转换类

    公司不准引入json-lib-2.x.jar所以只好自己写了一个基本类型的object转json的类,然后支持8种基本类型和javabean,list,map,array,使用putJSON方法,ke ...

  10. Yii的学习(4)--Active Record

    摘自Yii官网:http://www.yiiframework.com/doc/guide/1.1/zh_cn/database.ar 在官网原文的基础上添加了CDbCriteria的详细用法. 虽然 ...