一、Hinbernate中持久化类的关联关系

在数据库中,表表之间是通过外键关联的,在程序中是要转化为持久化类也就是(JAVA Bean)来实例的。

但在Hibernater中持久化的之间的映射关系,不是通外键建立关联,而是通过属性.主要有以下几种

  • 一对一,
  • 一对多(多对一)
  • 多对多

关联方向:

  • 单向关联
  • 双向关联

二、一对多单向关联关系

2.1、建立数据库表

班级表,和学生表,学生生通过班级表中的,班级编号为外键

--班级表
create table grade
(
gid number primary key, --班级ID
gname varchar2(50), --班级名称
gdesc varchar2(50) --班级介绍
);
--学生表
create table student
(
sid number primary key, --主键ID学生ID
sname varchar2(20), --学生姓名
sex varchar2(20), --学生性别
gid number references grade(gid) ---外键班级ID
);

2.2、建立持久化类和映射配置文件

班级和学生类

package entity;

import java.util.HashSet;
import java.util.Set; /*
* 班级类
*/
public class Grade implements java.io.Serializable { // Fields
private static final long serialVersionUID = 1L;
private int gid;
private String gname;
private String gdesc;
private Set<Student> students = new HashSet<Student> (); // Constructors /** default constructor */
public Grade() {
} /** minimal constructor */
public Grade(int gid) {
this.gid = gid;
} /** full constructor */
public Grade(int gid, String gname, String gdesc, Set<Student> students) {
this.gid = gid;
this.gname = gname;
this.gdesc = gdesc;
this.students = students;
} // Property accessors public int getGid() {
return this.gid;
} public void setGid(int gid) {
this.gid = gid;
} public String getGname() {
return this.gname;
} public void setGname(String gname) {
this.gname = gname;
} public String getGdesc() {
return this.gdesc;
} public void setGdesc(String gdesc) {
this.gdesc = gdesc;
} public Set<Student> getStudents() {
return this.students;
} public void setStudents(Set<Student> students) {
this.students = students;
} }

学生类

package entity;

/*
* 学生类
*/
public class Student implements java.io.Serializable { // Fields private static final long serialVersionUID = 1L;
private int sid; private String sname;
private String sex; // Constructors /** default constructor */
public Student() {
} /** minimal constructor */
public Student(int sid) {
this.sid = sid;
} /** full constructor */
public Student(int sid, String sname, String sex ) { this.sid = sid; this.sname = sname;
this.sex = sex;
} // Property accessors public int getSid() {
return this.sid;
} public void setSid(int sid) {
this.sid = sid;
} public String getSname() {
return this.sname;
} public void setSname(String sname) {
this.sname = sname;
} public String getSex() {
return this.sex;
} public void setSex(String sex) {
this.sex = sex;
} }

hibernate.cf.xml和班级、学生的配置文件

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory>
<property name="dialect">
org.hibernate.dialect.Oracle9Dialect
</property>
<property name="connection.url">
jdbc:oracle:thin:@localhost:1521:orcl
</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">
oracle.jdbc.OracleDriver
</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property> <mapping resource="entity/Grade.hbm.xml" />
<mapping resource="entity/Student.hbm.xml" /> </session-factory> </hibernate-configuration>

持久类配置先来学生类

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping>
<class name="entity.Student" table="STUDENT" schema="ROOT">
<id name="sid" type="java.lang.Integer">
<column name="SID" precision="22" scale="0" />
<generator class="assigned" />
</id>
<property name="sname" type="java.lang.String">
<column name="SNAME" length="20" />
</property>
<property name="sex" type="java.lang.String">
<column name="SEX" length="20" />
</property>
</class>
</hibernate-mapping>

班级类配置

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping>
<class name="entity.Grade" table="GRADE" schema="ROOT">
<id name="gid" type="java.lang.Integer">
<column name="GID" precision="22" scale="0" />
<generator class="assigned" />
</id>
<property name="gname" type="java.lang.String">
<column name="GNAME" length="50" />
</property>
<property name="gdesc" type="java.lang.String">
<column name="GDESC" length="50" />
</property>
<!--建立set属性,也可以建立list和持久化类中一致就行 -->
<set name="students">
<key>
<!--这里的列是指学生表中的班级编号 -->
<column name="GID" precision="22" scale="0" />
</key>
<!-- 通过class属性指定set的属性 -->
<one-to-many class="entity.Student" />
</set>
</class>
</hibernate-mapping>

测试类

package Test;

import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration; import entity.Grade;
import entity.Student; public class Demo1 { /**
* 测试类
*/
public static void main(String[] args) {
save();
find();
update(); } public static void save() {
// 声明班级对象,并赋值
Grade grade = new Grade();
grade.setGid(201504);
grade.setGname("Java一班");
grade.setGdesc("刚开始学习JAVA");
// 声明2个学生对象
Student stu1 = new Student();
stu1.setSid(201504012);
stu1.setSname("张三");
stu1.setSex("男"); Student stu2 = new Student();
stu2.setSid(201504013);
stu2.setSname("李四");
stu2.setSex("女"); // 将学生添加到班级
grade.getStudents().add(stu1);
grade.getStudents().add(stu2);
// 建立session
Session session = new Configuration().configure().buildSessionFactory()
.openSession();
// 开始事务
Transaction transaction = session.beginTransaction();
// 保存班级
session.save(grade);
// 保存学生
session.save(stu1);
session.save(stu2);
// 提交事务
transaction.commit();
// 关闭session
session.close();
} /*
* 将基中一个学生更改为别一个班级
*/
public static void update() {
// 声明班级对象,并赋值
Grade grade = new Grade();
grade.setGid(201506);
grade.setGname("Java二班");
grade.setGdesc("学习JAVA二年级");
// 获取一个学生的信息
// 建立session
Session session = new Configuration().configure().buildSessionFactory()
.openSession();
// 开始事务
Transaction transaction = session.beginTransaction();
Student stu1=(Student) session.get(Student.class, 201504013);
//将学生添加到这个新的班级
grade.getStudents().add(stu1);
// 保存班级
session.save(grade);
// 保存学生
session.save(stu1);
// 提交事务
transaction.commit();
// 关闭session
session.close();
} // 查询班级
public static void find() { // 建立session
Session session = new Configuration().configure().buildSessionFactory()
.openSession();
Grade g = (Grade) session.get(Grade.class, 201504);
System.out.println("班级信息:" + g.getGid() + "\t" + g.getGname()
+ g.getGdesc());
// 通过班级获取这个班级的学生信息
System.out.println("201504班的学生信息如下:");
Set<Student> set = g.getStudents();
for (Student stu : set) {
System.out.println(stu.getSid() + "\t" + stu.getSname() + "\t"
+ stu.getSex());
}
} }

以上只上单向关联,一般都会有双向关联

同样要在学生类中添加Grade 属性

在学生类的配置文件中配置关联字段

二、建立双向关联

2.1、更改学生类和配置文件

package entity;

/*
* 学生类
*/
public class Student implements java.io.Serializable { // Fields private static final long serialVersionUID = 1L;
private int sid;
private String sname;
private String sex;
//增加班级属性
private Grade grade; // Constructors /** default constructor */
public Student() {
} /** minimal constructor */
public Student(int sid) {
this.sid = sid;
} /** full constructor */
public Student(int sid, String sname, String sex ) { this.sid = sid; this.sname = sname;
this.sex = sex;
} // Property accessors public int getSid() {
return this.sid;
} public void setSid(int sid) {
this.sid = sid;
} public String getSname() {
return this.sname;
} public void setSname(String sname) {
this.sname = sname;
} public String getSex() {
return this.sex;
} public void setSex(String sex) {
this.sex = sex;
} public Grade getGrade() {
return grade;
} public void setGrade(Grade grade) {
this.grade = grade;
} }

配置文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping>
<class name="entity.Student" table="STUDENT" schema="ROOT">
<id name="sid" type="java.lang.Integer">
<column name="SID" precision="22" scale="0" />
<generator class="assigned" />
</id>
<property name="sname" type="java.lang.String">
<column name="SNAME" length="20" />
</property>
<property name="sex" type="java.lang.String">
<column name="SEX" length="20" />
</property>
<!--配置grade属性 -->
<many-to-one name="grade" class="entity.Grade">
<!--指定学生表中的外键 -->
<column name="GID" />
</many-to-one>
</class>
</hibernate-mapping>

2.2、测试类

建立双向关联后,就可以通过学生来获取班级信息

清空数据表中的数据

package Test;

import org.hibernate.Session;
import org.hibernate.cfg.Configuration; import entity.Student; public class Demo2 { /**
* 测试类
*/
public static void main(String[] args) {
 save();
findByStu();
} public static void findByStu(){
Session session = new Configuration().configure().buildSessionFactory()
.openSession();
//获取一个学生的信息 get方法为通过主键查询
Student stu=(Student) session.get(Student.class, 201504013);
System.out.println("学生信息:\t"+stu.getSid()+"\t"+stu.getSname()+"\t"+stu.getSex());
//通过学生信息得到班级信息
System.out.println("这个学生的班级信息:"+stu.getGrade().getGid()+"\t"+stu.getGrade().getGname()+"\t"+stu.getGrade().getGdesc());
}
}
public static void save() {
// 声明班级对象,并赋值
Grade grade = new Grade();
grade.setGid(201504);
grade.setGname("Java一班");
grade.setGdesc("刚开始学习JAVA");
// 声明2个学生对象
Student stu1 = new Student();
stu1.setSid(201504012);
stu1.setSname("张三");
stu1.setSex("男");
stu1.setGrade(grade); Student stu2 = new Student();
stu2.setSid(201504013);
stu2.setSname("李四");
stu2.setSex("女");
stu2.setGrade(grade);
// 将学生添加到班级
/*grade.getStudents().add(stu1);
grade.getStudents().add(stu2);*/
// 建立session
Session session = new Configuration().configure().buildSessionFactory()
.openSession();
// 开始事务
Transaction transaction = session.beginTransaction();
// 保存班级
session.save(grade);
// 保存学生
session.save(stu1);
session.save(stu2);
// 提交事务
transaction.commit();
// 关闭session
session.close();
}

三、级联保存和删除

能不能只保存学生时,同时保存班级呢,或者保存班级时,同时保存学生呢

3.1、cascade属性

保存班级时,同时保存学生信息

修改班级配置,在set标签中添加cascade属性,设置为save-update

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping>
<class name="entity.Grade" table="GRADE" schema="ROOT">
<id name="gid" type="java.lang.Integer">
<column name="GID" precision="22" scale="0" />
<generator class="assigned" />
</id>
<property name="gname" type="java.lang.String">
<column name="GNAME" length="50" />
</property>
<property name="gdesc" type="java.lang.String">
<column name="GDESC" length="50" />
</property>
<!--建立set属性,也可以建立list和持久化类中一致就行 -->
<set name="students" cascade="save-update">
<key>
<!--这里的列是指学生表中的班级编号 -->
<column name="GID" precision="22" scale="0" />
</key>
<!-- 通过class属性指定set的属性 -->
<one-to-many class="entity.Student" />
</set>
</class>
</hibernate-mapping>

测试类

package Test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration; import entity.Grade;
import entity.Student; public class Demo3 { /**
* @param args
*/
public static void main(String[] args) {
save(); }
public static void save() {
// 声明班级对象,并赋值
Grade grade = new Grade();
grade.setGid(201504);
grade.setGname("Java一班");
grade.setGdesc("刚开始学习JAVA");
// 声明2个学生对象
Student stu1 = new Student();
stu1.setSid(201504012);
stu1.setSname("张三");
stu1.setSex("男");
stu1.setGrade(grade); Student stu2 = new Student();
stu2.setSid(201504013);
stu2.setSname("李四");
stu2.setSex("女");
stu2.setGrade(grade);
// 将学生添加到班级
grade.getStudents().add(stu1);
grade.getStudents().add(stu2);
// 建立session
Session session = new Configuration().configure().buildSessionFactory()
.openSession();
// 开始事务
Transaction transaction = session.beginTransaction();
// 保存班级
session.save(grade);
// 保存学生
//session.save(stu1);
//session.save(stu2);
// 提交事务
transaction.commit();
// 关闭session
session.close();
}
}

反之,在学生类的配置文件one-many中添加cascade属性设置为save-update

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping>
<class name="entity.Student" table="STUDENT" schema="ROOT">
<id name="sid" type="java.lang.Integer">
<column name="SID" precision="22" scale="0" />
<generator class="assigned" />
</id>
<property name="sname" type="java.lang.String">
<column name="SNAME" length="20" />
</property>
<property name="sex" type="java.lang.String">
<column name="SEX" length="20" />
</property>
<!--配置grade属性 -->
<many-to-one name="grade" class="entity.Grade" cascade="save-update">
<!--指定学生表中的外键 -->
<column name="GID" />
</many-to-one>
</class>
</hibernate-mapping>
package Test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration; import entity.Grade;
import entity.Student; public class Demo3 { /**
* @param args
*/
public static void main(String[] args) {
save(); }
public static void save() {
// 声明班级对象,并赋值
Grade grade = new Grade();
grade.setGid(201504);
grade.setGname("Java一班");
grade.setGdesc("刚开始学习JAVA");
// 声明2个学生对象
Student stu1 = new Student();
stu1.setSid(201504012);
stu1.setSname("张三");
stu1.setSex("男");
stu1.setGrade(grade); Student stu2 = new Student();
stu2.setSid(201504013);
stu2.setSname("李四");
stu2.setSex("女");
stu2.setGrade(grade);
// 将学生添加到班级
grade.getStudents().add(stu1);
grade.getStudents().add(stu2);
// 建立session
Session session = new Configuration().configure().buildSessionFactory()
.openSession();
// 开始事务
Transaction transaction = session.beginTransaction();
// 保存班级
//session.save(grade);
// 保存学生
session.save(stu1);
session.save(stu2);
// 提交事务
transaction.commit();
// 关闭session
session.close();
}
}

3.2、inverse属性

首先在班级类中设置invers属性为false时,删除班级

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping>
<class name="entity.Grade" table="GRADE" schema="ROOT">
<id name="gid" type="java.lang.Integer">
<column name="GID" precision="22" scale="0" />
<generator class="assigned" />
</id>
<property name="gname" type="java.lang.String">
<column name="GNAME" length="50" />
</property>
<property name="gdesc" type="java.lang.String">
<column name="GDESC" length="50" />
</property>
<!--建立set属性,也可以建立list和持久化类中一致就行 -->
<set name="students" cascade="save-update" inverse="false">
<key>
<!--这里的列是指学生表中的班级编号 -->
<column name="GID" precision="22" scale="0" />
</key>
<!-- 通过class属性指定set的属性 -->
<one-to-many class="entity.Student" />
</set>
</class>
</hibernate-mapping>

测试类

package Test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration; import entity.Grade;
import entity.Student; public class Demo4 { /**
* @param args
*/
public static void main(String[] args) {
delete() ; } public static void delete() { // 建立session
Session session = new Configuration().configure().buildSessionFactory()
.openSession();
// 开始事务
Transaction transaction = session.beginTransaction();
// 保存班级
Grade grade=(Grade) session.get(Grade.class, 201504);
// 保存学生
session.delete(grade);
// 提交事务
transaction.commit();
// 关闭session
session.close();
}
}

结果:发现班级表中的班级已经删除,而学生表中数据没有删除,只是GID字段为NULL

下面将inverse设置为true时,添加新学生,和新的班级

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping>
<class name="entity.Grade" table="GRADE" schema="ROOT">
<id name="gid" type="java.lang.Integer">
<column name="GID" precision="22" scale="0" />
<generator class="assigned" />
</id>
<property name="gname" type="java.lang.String">
<column name="GNAME" length="50" />
</property>
<property name="gdesc" type="java.lang.String">
<column name="GDESC" length="50" />
</property>
<!--建立set属性,也可以建立list和持久化类中一致就行 -->
<set name="students" cascade="save-update" inverse="true">
<key>
<!--这里的列是指学生表中的班级编号 -->
<column name="GID" precision="22" scale="0" />
</key>
<!-- 通过class属性指定set的属性 -->
<one-to-many class="entity.Student" />
</set>
</class>
</hibernate-mapping>

测试类

package Test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration; import entity.Grade;
import entity.Student; public class Demo4 { /**
* @param args
*/
public static void main(String[] args) {
delete() ; } public static void delete() { // 声明班级对象,并赋值
Grade grade = new Grade();
grade.setGid(201509);
grade.setGname("Java三班");
grade.setGdesc("ASP.NET");
// 声明2个学生对象
Student stu1 = new Student();
stu1.setSid(201509009);
stu1.setSname("王五");
stu1.setSex("女");
stu1.setGrade(grade); Student stu2 = new Student();
stu2.setSid(201509045);
stu2.setSname("赵六");
stu2.setSex("女");
stu2.setGrade(grade); // 建立session
Session session = new Configuration().configure().buildSessionFactory()
.openSession();
// 开始事务
Transaction transaction = session.beginTransaction(); // 保存学生
session.save(stu1);
session.save(stu2);
// 提交事务
transaction.commit();
// 关闭session
session.close();
}
}

结果发现,我并没有用班级添加学生,也没有保存班级,只是保存了学生,班级信息一起保存了

Hibernate(六)一对多映射(多对一)的更多相关文章

  1. 一口一口吃掉Hibernate(六)——多对多关联映射

    今天来说说hibernate中的多对多关联映射,多对多关联映射涉及到单向映射和双向映射2种. 首先举个多对多关联例子:用户User和角色Role,一个用户可以属于多个角色,一个角色可以有多个用户.这就 ...

  2. hibernate进阶--一对多映射配置

    hibernate作为一款优秀的ORM框架,广受大家喜爱,也被Java社区公认为持久层的首选.虽然jdbc为Java数据库操 作带来了诸多便利,但是并没有统一SQL语句的写法,而且具体操作数据库的代码 ...

  3. Hibernate-ORM:12.Hibernate中的多对多关联关系

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客将讲述Hibernate中的多对多关联关系的操作,准备的篇幅较少,望海涵 一,讲述多对多 多对多的关联 ...

  4. Hibernate中双向多对多的两种配置方式

    Hibernate中双向多对多的两种配置方式 1.建立多对多双向关联关系 package cn.happy.entitys; import java.util.HashSet; import java ...

  5. Hibernate ManyToOne Mappings 多对一关联映射

    Hibernate ManyToOne Mappings 多对一关联映射 Hibernate框架的使用步骤: 1.创建Hibernate的配置文件(hibernate.cfg.xml)2.创建持久化类 ...

  6. hibernate关联关系(多对多)

    数据库的多对多数据库中不能直接映射多对多 处理:创建一个桥接表(中间表),将一个多对多关系转换成两个一对多 注:数据库多表联接查询 永远就是二个表的联接查询 注2:交叉连接 注3:外连接:left(左 ...

  7. Hibernate(六)——多对多关联映射

    前面几篇文章已经较讲解了三大种关联映射,多对多映射就非常简单了,不过出于对关联映射完整性的考虑,本文还是会简要介绍下多对多关联映射. 1.单向多对多关联映射 情景:一个用户可以有多个角色,比如数据录入 ...

  8. --------------Hibernate学习(四) 多对一映射 和 一对多映射

    现实中有很多场景需要用到多对一或者一对多,比如上面这两个类图所展现出来的,一般情况下,一个部门会有多名员工,一名员工只在一个部门任职. 多对一关联映射 在上面的场景中,对于Employee来说,它跟D ...

  9. hibernate之一对多映射

    目录 第一章 课程简介 第二章 Hibernate中的单向一对多关联 2-1 一对多映射简介 2-2 hibernate的基础配置 2-3 创建HibernateUtil工具类 2-4 在mysql数 ...

随机推荐

  1. Alpha冲刺(4/10)——追光的人

    1.队友信息 队员学号 队员博客 221600219 小墨 https://www.cnblogs.com/hengyumo/ 221600240 真·大能猫 https://www.cnblogs. ...

  2. js中什么是对象,对象的概念是什么?

    我们一直在用对象 可是你真的理解对象吗,js中有一个说法是一切皆对象,其实这里说的应该是 一切皆可看作对象 对象就是可以拥有属性和方法的一个集合 士兵就是一个对象,它拥有身高体重的属性,保家卫国,吃饭 ...

  3. POJ 1330 Nearest Common Ancestors (LCA,dfs+ST在线算法)

    Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14902   Accept ...

  4. Tasker to proximity screen off

    If you are using proximity screen off pro or smart screen off, you may know how convenient it is to ...

  5. 运用Android ROM Manager应用安装ClockworkMod Recovery的详细教程

    在安装ClockworkMod Recovery恢复模式之前,建议先认识下Google Android平台的ClockworkMod Recovery恢复模式 对于Android ROM Manage ...

  6. 通过ExchangeService 发送邮件

    ExchangeService service = new ExchangeService(); service.Url = new Uri("https://***(host)/ews/e ...

  7. react-native开发总结

    项目地址:http://liu12fei08fei.github.io/blog/41react-native.html 说明 • 项目总结代码地址 • 从项目开始启动(2018-07-02)到项目进 ...

  8. axure8.1可用授权码

    Licensee: University of Science and Technology of China (CLASSROOM)Key: DTXRAnPn1P65Rt0xB4eTQ+4bF5IU ...

  9. C#程序集系列01,用记事本编写C#,IL代码,用DOS命令编译程序集,运行程序

    本篇主要体验:编写C#,IL代码,用"VS2012开发人员命令提示"编译成程序集,并运行程序. □ C#文件编译为程序集 →在F盘创建as文件夹→在as文件夹下创建MyClass. ...

  10. andriod 浏览文件

    protected void browse() { Intent it = new Intent(Intent.ACTION_GET_CONTENT); //创建动作为 "选取" ...