关联关系映射:

  关联关系,是使用最多的一种关系,非常重要。在内存中反映为实体关系,映射到DB中为主外键关系。实体间的关联,即对外键的维护。关联关系的发生,即对外键数据的改变。

  外键:外面的主键,即,使用其它表的主键值作为自已的某字段的取值。

  (1) 基本概念:

    关联属性:Java代码的实体类定义中,声明的另一个实例类类型或其集合类型的属性,称为关联属性。

    关联关系维护:关联关系的维护,也称为外键维护,即为外键字段赋值。Hibernate默认情况下,关联的双方都具有维护权。即在代码中均可通过调用自己关联属性的set方法来建立关联关系。反映到数据库中,即是为外键字段赋值。

           不过,由于外键是建立在多方表中的,所以对于外键的维护方式,即为外键字段赋值的方式,一方维护与多方维护,其底层执行是不同的。
           若关联关系由一方维护,只能通过update语句来完成。若关联关系由多方维护,通过insert语句来完成。
           虽然双方均具有维护权,但一方同时具有放弃维护权的能力。通过对一方关联属性inverse=“true”设置,即可放弃关联关系维护权,将维护权完全交给多方。

    预处理语句:所谓预处理语句,即当前先不执行,等后面条件成熟,或程序运行完毕再执行的语句。

          当一方具有关联关系的维护权,并且执行save(一方对象)时,会产生一条update预处理语句,用于维护外键值。当多方具有关联关系的维护权,并且执行save(多方对象)时,会产生一条insert预处理语句,用于维护外键值。

    级联关系:当对某一类的对象a进行操作,如增加、删除、修改时,同时会自动对另一类的某对象b进行相同的操作。此时称,对象a、b具有级联关系,对象b为对象a的级联对象。

         级联操作是通过映射文件的cascade属性设置的。该属性的值较多,其介绍如下:

          none:在保存、更新或删除当前对象时,忽略其他关联的对象,即不使用级联。它是默认值。
          save-update:当通过Session的save()、update()、saveOrUpdate()方法来保存或更新当前对象时,将级联到其他DB中的相关联的表。
            delete:当通过Session的delete()方法删除当前对象时,将级联删除所有关联的对象。

          all:包含save-update及delete级联的所有行为。另外,当对当前对象执行lock()操作时,也会对所有关联的持久化对象执行lock()操作。
          delete-orphan:删除所有和当前对象解除关联关系的对象。

          all-delete-orphan:包含all和delete-orphan级联的所有行为。

    关联方向:(1)单向关联:指具有关联关系的实体对象间的加载与访问关系是单向的。即,只有一个实体对象可以加载和访问对方,但对方是看不到另一方的。
         (2)双向关联 :指具有关联关系的实体对象间的加载与访问关系是双向的。即,任何一方均可加载和访问另一方。

    关联数量:实体对象间的关系,从数量上可以划分为:1:1,1:n,n:1,m:n

    总结底层执行:一对多关系中,一方维护关联关系,先插入多方数据,后插入一方数据,最后update多方表中的外键值(???是否正确);多方维护关联关系,先插入一方数据,后插入多方数据,在插入多方数据的同时插入外键值;

           多对多关系中,哪一方维护关联关系,就是哪一方数据先插入,再插入关联方数据,最后插入中间表数据。

  (2) 1:n单向关联(由一方维护关联关系):

    一方实体类代码:

 package com.tongji.beans;

 import java.util.HashSet;
import java.util.Set; public class Country {
private Integer cid;
private String cname;
private Set<Minister> ministers; //关联属性 public Country() {
super();
ministers = new HashSet<Minister>();
} public Country(String cname) {
this();
this.cname = cname;
} public Integer getCid() {
return cid;
} public void setCid(Integer cid) {
this.cid = cid;
} public String getCname() {
return cname;
} public void setCname(String cname) {
this.cname = cname;
} public Set<Minister> getMinisters() {
return ministers;
} public void setMinisters(Set<Minister> ministers) {
this.ministers = ministers;
} @Override
public String toString() {
return "Country [cid=" + cid + ", cname=" + cname + ", ministers=" + ministers + "]";
} }

    一方映射文件代码:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.tongji.beans">
<class name="Country">
<id name="cid">
<generator class="native"/>
</id>
<property name="cname"/>
<!-- 对关联属性的映射,inverse=true,表示一方放弃关联关系的维护权,这个不应该这么设置,只是为了演示错误 -->
<set name="ministers" cascade="save-update" inverse="true">
<key column="countryId"/>
<one-to-many class="Minister"/>
</set>
</class>
</hibernate-mapping>

     其中,column是外键的名称

     测试代码:

 @Test
public void test03() {
//1. 获取Session
Session session = HbnUtils.getSession();
try {
//2. 开启事务
session.beginTransaction();
//3. 操作
Minister minsiter1 = new Minister("aaa");
Minister minsiter2 = new Minister("bbb");
Minister minsiter3 = new Minister("ccc"); Country country = new Country("USA");
//关联的建立在这里完成
country.getMinisters().add(minsiter1);
country.getMinisters().add(minsiter2);
country.getMinisters().add(minsiter3); session.save(country);
//4. 事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
//5. 事务回滚
session.getTransaction().rollback();
}
}

  (2) 1:n双向关联:

    一方实体类代码和一方映射文件代码同上;

    多方实体类代码:

 package com.tongji.beans;

 public class Minister {
private Integer mid;
private String mname;
private Country country; //关联属性 public Minister() {
super();
} public Minister(String mname) {
super();
this.mname = mname;
} public Integer getMid() {
return mid;
} public void setMid(Integer mid) {
this.mid = mid;
} public String getMname() {
return mname;
} public void setMname(String mname) {
this.mname = mname;
} public Country getCountry() {
return country;
} public void setCountry(Country country) {
this.country = country;
} @Override
public String toString() {
return "Minister [mid=" + mid + ", mname=" + mname + "]";
} }

    多方映射文件代码:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.tongji.beans">
<class name="Minister">
<id name="mid">
<generator class="native"/>
</id>
<property name="mname"/>
<!-- 关联属性名 -->
<many-to-one name="country" cascade="save-update"
class="Country" column="countryId"/>
</class>
</hibernate-mapping>

    测试代码:

 package com.tongji.test;

 import org.hibernate.Session;
import org.junit.Test; import com.tongji.beans.Country;
import com.tongji.beans.Minister;
import com.tongji.utils.HbnUtils; public class MyTest {
@Test
public void test00() {
//1. 获取Session
Session session = HbnUtils.getSession();
try {
//2. 开启事务
session.beginTransaction();
//3. 操作
Minister minister = new Minister("aaa"); Country country = new Country("USA");
//Country方在维护关联关系
country.getMinisters().add(minister); session.save(country);
//4. 事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
//5. 事务回滚
session.getTransaction().rollback();
}
} @Test
public void test01() {
//1. 获取Session
Session session = HbnUtils.getSession();
try {
//2. 开启事务
session.beginTransaction();
//3. 操作
Minister minister = new Minister("aaa"); Country country = new Country("USA");
//Minister方在维护关联关系
minister.setCountry(country); //谁在维护关联关系,就save()谁
session.save(minister);
//4. 事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
//5. 事务回滚
session.getTransaction().rollback();
}
}
}

  (3) 自关联:

    实体类代码:

 package com.tongji.beans;

 import java.util.HashSet;
import java.util.Set; //新闻栏目
public class NewsLabel {
private Integer id;
private String name; //栏目名称
private String content; //栏目内容
private NewsLabel parentNewsLabel; //父栏目
private Set<NewsLabel> childNewsLabels; //子栏目 public NewsLabel() {
childNewsLabels = new HashSet<NewsLabel>();
} public NewsLabel(String name, String content) {
this();
this.name = name;
this.content = content;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getContent() {
return content;
} public void setContent(String content) {
this.content = content;
} public NewsLabel getParentNewsLabel() {
return parentNewsLabel;
} public void setParentNewsLabel(NewsLabel parentNewsLabel) {
this.parentNewsLabel = parentNewsLabel;
} public Set<NewsLabel> getChildNewsLabels() {
return childNewsLabels;
} public void setChildNewsLabels(Set<NewsLabel> childNewsLabels) {
this.childNewsLabels = childNewsLabels;
} @Override
public String toString() {
return "NewsLabel [id=" + id + ", name=" + name + ", content=" + content + "]";
} }

    映射文件代码:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.tongji.beans">
<class name="NewsLabel">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="content"/>
<!-- 站在一方角度 -->
<set name="childNewsLabels" cascade="save-update">
<key column="pid"/>
<one-to-many class="NewsLabel"/>
</set>
<!-- 站在多方角度 -->
<many-to-one name="parentNewsLabel" cascade="save-update"
class="NewsLabel" column="pid"/>
</class>
</hibernate-mapping>

    测试代码:

 package com.tongji.test;

 import org.hibernate.Session;
import org.junit.Test; import com.tongji.beans.NewsLabel;
import com.tongji.utils.HbnUtils; public class MyTest {
//让父方栏目维护关联关系,即一方维护
@Test
public void test00() {
//1. 获取Session
Session session = HbnUtils.getSession();
try {
//2. 开启事务
session.beginTransaction();
//3. 操作
NewsLabel footballNews = new NewsLabel("足球新闻","国足国足国足国足");
NewsLabel basketballNews = new NewsLabel("篮球新闻","登哥登哥登哥登哥"); NewsLabel sportsNews = new NewsLabel("体育新闻","奥运奥运奥运奥运"); sportsNews.getChildNewsLabels().add(footballNews);
sportsNews.getChildNewsLabels().add(basketballNews); session.save(sportsNews); //4. 事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
//5. 事务回滚
session.getTransaction().rollback();
}
} //让子方栏目维护关联关系,即多方维护
@Test
public void test01() {
//1. 获取Session
Session session = HbnUtils.getSession();
try {
//2. 开启事务
session.beginTransaction();
//3. 操作
NewsLabel basketballNews = new NewsLabel("篮球新闻","登哥登哥登哥登哥"); NewsLabel sportsNews = new NewsLabel("体育新闻","奥运奥运奥运奥运"); basketballNews.setParentNewsLabel(sportsNews); session.save(basketballNews); //4. 事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
//5. 事务回滚
session.getTransaction().rollback();
}
}
}

  (4) n:1单向关联(由多方来维护关联关系):

    一方实体类代码和一方映射文件代码为原来不考虑关联时候的样子,多方实体类代码和多方映射文件代码同(3)1:n双向关联,测试代码同(3)1:n双向关联的多方维护部分。

  (5)n:m单向关联:

    维护关联关系的一方的实体类代码:

 package com.tongji.beans;

 import java.util.HashSet;
import java.util.Set; public class Student {
private Integer sid;
private String sname;
private Set<Course> courses; public Student() {
courses = new HashSet<Course>();
} public Student(String sname) {
this();
this.sname = sname;
} 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 Set<Course> getCourses() {
return courses;
} public void setCourses(Set<Course> courses) {
this.courses = courses;
} @Override
public String toString() {
return "Student [sid=" + sid + ", sname=" + sname + "]";
} }

    维护关联关系的一方的映射文件代码:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.tongji.beans">
<class name="Student">
<id name="sid">
<generator class="native"/>
</id>
<property name="sname"/>
<!-- 关联属性的映射 -->
<set name="courses" cascade="save-update" table="middle"> <!-- table指定多对多关系的中间表 -->
<key column="studentId"/> <!-- 指定当前类在中间表中对应的外键 -->
<many-to-many class="Course" column="courseId"/> <!-- 指定关联类在中间表中对应的外键 -->
</set>
</class>
</hibernate-mapping>

    测试代码:

 package com.tongji.test;

 import org.hibernate.Session;
import org.junit.Test; import com.tongji.beans.Course;
import com.tongji.beans.Student;
import com.tongji.utils.HbnUtils; public class MyTest {
//第一种解决方案
@Test
public void test00() {
//1. 获取Session
Session session = HbnUtils.getSession();
try {
//2. 开启事务
session.beginTransaction();
//3. 操作
Course course1 = new Course("Struts2");
Course course2 = new Course("Hibernate5");
Course course3 = new Course("Sring4"); Student student1 = new Student("张三");
Student student2 = new Student("李四"); student1.getCourses().add(course1);
student1.getCourses().add(course2); student2.getCourses().add(course1);
student2.getCourses().add(course3); session.save(student1);
session.save(student2);
//4. 事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
//5. 事务回滚
session.getTransaction().rollback();
}
} }

   (6)n:m双向关联:

      上述另一方实体类代码:

 package com.tongji.beans;

 import java.util.HashSet;
import java.util.Set; public class Course {
private Integer cid;
private String cname;
private Set<Student> students; public Course() {
students = new HashSet<Student>();
} public Course(String cname) {
this();
this.cname = cname;
} public Integer getCid() {
return cid;
} public void setCid(Integer cid) {
this.cid = cid;
} public String getCname() {
return cname;
} public void setCname(String cname) {
this.cname = cname;
} public Set<Student> getStudents() {
return students;
} public void setStudents(Set<Student> students) {
this.students = students;
} @Override
public String toString() {
return "Course [cid=" + cid + ", cname=" + cname + "]";
} }

    上述另一方映射文件代码:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.tongji.beans">
<class name="Course">
<id name="cid">
<generator class="native"/>
</id>
<property name="cname"/>
<!-- 关联属性映射-->
<set name="students" cascade="save-update" table="middle">
<key column="courseId"/>
<many-to-many class="Student" column="studentId"/>
</set>
</class>
</hibernate-mapping>

    测试代码:

 package com.tongji.test;

 import org.hibernate.Session;
import org.junit.Test; import com.tongji.beans.Course;
import com.tongji.beans.Student;
import com.tongji.utils.HbnUtils; public class MyTest {
@Test
public void test00() {
//1. 获取Session
Session session = HbnUtils.getSession();
try {
//2. 开启事务
session.beginTransaction();
//3. 操作
Course course1 = new Course("Struts2");
Course course2 = new Course("Hibernate5");
Course course3 = new Course("Sring4"); Student student1 = new Student("张三");
Student student2 = new Student("李四"); student1.getCourses().add(course1);
student1.getCourses().add(course2); student2.getCourses().add(course1);
student2.getCourses().add(course3); session.save(student1);
session.save(student2);
//4. 事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
//5. 事务回滚
session.getTransaction().rollback();
}
} @Test
public void test01() {
//1. 获取Session
Session session = HbnUtils.getSession();
try {
//2. 开启事务
session.beginTransaction();
//3. 操作
Course course1 = new Course("Struts2");
Course course2 = new Course("Hibernate5");
Course course3 = new Course("Sring4"); Student student1 = new Student("张三");
Student student2 = new Student("李四"); course1.getStudents().add(student1);
course1.getStudents().add(student2); course2.getStudents().add(student2); course3.getStudents().add(student1); session.save(course1);
session.save(course2);
session.save(course3);
//4. 事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
//5. 事务回滚
session.getTransaction().rollback();
}
} }

Hibernate5--课程笔记5的更多相关文章

  1. Linux内核分析课程笔记(一)

    linux内核分析课程笔记(一) 冯诺依曼体系结构 冯诺依曼体系结构实际上就是存储程序计算机. 从两个层面来讲: 从硬件的角度来看,冯诺依曼体系结构逻辑上可以抽象成CPU和内存,通过总线相连.CPU上 ...

  2. (1/18)重学Standford_iOS7开发_iOS概述_课程笔记

    写在前面:上次学习课程对iOS还是一知半解,由于缺乏实践,看公开课的视频有时不能很好地领会知识.带着问题去学习永远是最好的方法,接触一段时间iOS开发以后再来看斯坦福iOS公开课,又会有许多新的发现, ...

  3. Andrew Ng机器学习课程笔记(五)之应用机器学习的建议

    Andrew Ng机器学习课程笔记(五)之 应用机器学习的建议 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/7368472.h ...

  4. Andrew Ng机器学习课程笔记--week1(机器学习介绍及线性回归)

    title: Andrew Ng机器学习课程笔记--week1(机器学习介绍及线性回归) tags: 机器学习, 学习笔记 grammar_cjkRuby: true --- 之前看过一遍,但是总是模 ...

  5. Andrew Ng机器学习课程笔记--汇总

    笔记总结,各章节主要内容已总结在标题之中 Andrew Ng机器学习课程笔记–week1(机器学习简介&线性回归模型) Andrew Ng机器学习课程笔记--week2(多元线性回归& ...

  6. Andrew 机器学习课程笔记

    Andrew 机器学习课程笔记 完成 Andrew 的课程结束至今已有一段时间,课程介绍深入浅出,很好的解释了模型的基本原理以及应用.在我看来这是个很好的入门视频,他老人家现在又出了一门 deep l ...

  7. 操作系统学习笔记----进程/线程模型----Coursera课程笔记

    操作系统学习笔记----进程/线程模型----Coursera课程笔记 进程/线程模型 0. 概述 0.1 进程模型 多道程序设计 进程的概念.进程控制块 进程状态及转换.进程队列 进程控制----进 ...

  8. 《CSS动画实用技巧》课程笔记

    概述 这是我学习[CSS动画实用技巧][1]的课程笔记 常用动画属性--transition [常用动画属性--transition][2] .change img{ display:block; w ...

  9. Deeplearning.ai课程笔记--汇总

    从接触机器学习就了解到Andrew Ng的机器学习课程,后来发现又出来深度学习课程,就开始在网易云课堂上学习deeplearning.ai的课程,Andrew 的课真是的把深入浅出.当然学习这些课程还 ...

  10. selenium课程笔记

    selenium课程笔记第一天(2017-7-1) 一.配置火狐浏览器 运行:firefox.exe -p -no -remote selenium课程笔记第二天 用Eclipse+java+sele ...

随机推荐

  1. “Will not add file alias 'samefile' ('SameFile' already exists in index)” when `git add/commit` operation

    从远程仓库pull下来的代码有两个类类名首字母小写出现如下情况 然后我想删了重新写一下(就是把这个类删了,代码复制到名字正确的类里面),然后commit的时候出现这个错误,后来删一个commit一下, ...

  2. .Net程序员学用Oracle系列(1):导航目录

    本人从事基于 Oracle 的 .Net 企业级开发近三年,在此之前学习和使用的都是 (MS)SQL Server.未曾系统的了解过 Oracle,所以长时间感到各种不习惯.不方便.怪异和不解,常会遇 ...

  3. 基本的SQL语句

    一些常用的SQL语句大全参考:http://www.cnblogs.com/acpe/p/4970765.html 这篇博文整理的比较全,我摘抄一些基本常用的. 创建数据库 CREATE DATABA ...

  4. “System.FormatException”类型的异常在 mscorlib.dll 中发生,但未在用户代码中进行处理 其他信息: 该字符串未被识别为有效的 DateTime。

    前台用过jquery ajax将值传递到 后台的一般处理程序 并且报了这个异常 原因是:前台传递过来的时间格式不对  需要把 "/"换成 "-"   例如:20 ...

  5. H3 BPM报销流程开发示例

    以报销流程为示例,介绍H3 BPM的流程开发过程. 报销流程的表单效果如下: 审核流程为填写报销申请.主管审核.总监审核(1000以上).出纳付款,显示如下: 步骤一:准备工作 使用管理员账号的登录H ...

  6. Head First设计模式——策略设计模式

    策略设计模式 说在前面的话 入软件一年啦,平心而论,总算不限于只会钻研些基础的语言语法了,数据结构和算法也恶补的差不多了.所以~趁着现在一边实习一边啃<Head First设计模式>的功夫 ...

  7. nodejs中express安装失败解决方法

    http://jingyan.baidu.com/article/922554468a3466851648f419.html

  8. node-canvas

    1.使用之前需要预先安装  Cairo 本人安装遇到各种各样的坑,可以参考这里来填坑:https://github.com/Automattic/node-canvas/wiki/Installati ...

  9. 2016-2017 CT S03E02: Codeforces Trainings Season 3 Episode 2

    A HHPaint B Square Root C Interesting Places D Road to Home E Ant and apples F Square G Pair H The F ...

  10. assert的基本用法

    assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制,如C,C++和Eiffel等,但是支持的形式不尽相同,有的是通过语言本身.有的是通过库函数等.另外,从理论上来 ...