关联关系映射:

  关联关系,是使用最多的一种关系,非常重要。在内存中反映为实体关系,映射到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. Spring中AOP的模拟实现

    什么是AOP? 面向切面编程(AOP)完善spring的依赖注入(DI),面向切面编程在spring中主要表现为两个方面 1.面向切面编程提供声明式事务管理 2.spring支持用户自定义的切面 面向 ...

  2. 机器学习实战kNN之手写识别

    kNN算法算是机器学习入门级绝佳的素材.书上是这样诠释的:“存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都有标签,即我们知道样本集中每一条数据与所属分类的对应关系.输入没有标签的新数据 ...

  3. TreeView控制消息

    控制消息的作用 通过发送消息到Treeview控件, 就能够控机Treeview控件.常用的控制有: 获取被点击的节点 获取节点的文本 设置节点的文本 获取节点的父节点 获取节点的子节点 TVM_GE ...

  4. iOS BUG的解决

    当iOS程序报这样的错误 ld:261 dulicate symbols for architecture x86_64 clang:error:linker command failed with ...

  5. 自己通过centos6.5配置NFS 成功后的笔记,希望对需要的人有点点帮助吧!

         环境介绍:            服务器:centos  172.16.250.170            客户端:centos  172.16.250.172     先用rpm -qa ...

  6. aop为系统添加操作日志,注入或配置声明的方式来实现

    最近做项目实现操作记录添加日志,由于aop这两种实现方式各有优缺点,所以都实现了一下以后根据具体业务选择. 1实现方式一注入: 1.1首先在xml中开启aop注入,需要引入的包此处省略,可百度自己查找 ...

  7. ios微信支付成功后点击左上角返回不走回调的问题

    最近做微信支付发现ios9以后出现的跳转其他app后左上角有返回xxx功能会影响微信支付回调,情况如图 返回后不走下面的方法 - (BOOL)application:(UIApplication *) ...

  8. 修改searchBar的返回按钮的显示文字

    #pragma mark 搜索框的代理方法,搜索输入框获得焦点(聚焦) - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar { ...

  9. js-数据转换

    <script type="text/javascript"> var msg = '{"code": 0, "data": 2 ...

  10. inux按照CPU、内存、磁盘IO、网络性能监测

    http://my.oschina.net/chape/blog/159640 系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估.监测,而且是一个长 ...