文档章节

Hibernate_03

勤劳的开发者px
 勤劳的开发者px
发布于 2017/09/04 16:50
字数 3167
阅读 2
收藏 0
点赞 0
评论 0

一对多关系

概念

一对多关系是关系型数据库中两个表之间的一种关系。在ORM中,如何通过对象描述表之间的关系,是ORM核心。通常 在数据库层级中,两表之间是有主外键关系的。

数据库方式建立一对多模型

-- 用户表
CREATE TABLE t_user (
	u_id INT PRIMARY KEY AUTO_INCREMENT,
	u_name VARCHAR(255),
	u_age INT
);
-- 号码表
CREATE TABLE t_phone (
	p_id INT PRIMARY KEY AUTO_INCREMENT,
	p_number VARCHAR(255),
	fk_u_id INT
);
-- 用户表和电话表的主外键关系
ALTER TABLE t_phone
ADD CONSTRAINT fk_user_phone FOREIGN KEY(fk_u_id) REFERENCES t_user(u_id); 

代码生成一对多模型步骤

  1. 导入Hibernate框架的Jar
  2. 新建持久化类:  在多方持久类中无需新建外键属性
  3. 配置映射文件: 配置中无需为外键属性提供<property>标签
  4.           关系结构描述
  5. 配置hibernate启动文件
  6. 通过代码生成表结构

一方结构描述

持久化类中描述

在一方的持久化类中,通过set集合描述多方,将多方集合作为自己的属性存在。

private Set<Phone> phones = new HashSet<>();

映射文件描述

在一方的class标签中添加 标签

<set name="phones">
<!-- 外键列名,多方中 -->
<key column="u_id"/>
<one-to-many class="org.itheima.hibernate.domain.Phone" />
</set>
  • set标签中name属性: 持久化类中多方set集合的属性名称
  • key标签中的column属性: 外键名称。多方表中的外键列名,与一方表的主键构成主外键关系。
  • one-to-many标签: 代表当前是一方(一方)
  • one-to-many标签中的class: 指向多方的类名

多方结构描述

持久化类中描述

在多方的持久化类中,通过一方对象类型描述一方,将一方对象作为自己属性存在。

private User user;

映射文件描述

在多方的class标签中添加 标签

<many-to-one 
name="user" 
class="org.itheima.hibernate.domain.User" 
column="fk_u_id" />
  • 通过many-to-one标签标记当前是多方。
  • name属性: 多方持久类中一方的属性名称。
  • class属性: 多方持久类中一方的属性对应的类名。
  • column属性: 多方数据库表中的外键名称,此外键是关联一方数据库表的主键的。

级联操作的概念

  • 当对主对象进行某种操作时是否对其关联的从对象也作类似的操作
  • cascade的取值
    • none:不使用级联
    • save-update:级联保存或更新
    • delete:级联删除
    • delete-orphan:孤儿删除.(注意:只能应用在一对多关系)
    • all:除了delete-orphan的所有情况.(包含save-update delete)
    • all-delete-orphan:包含了delete-orphan的所有情况.(包含save-update delete delete-orphan)

一方的级联操作

级联保存和修改

在一方的映射文件中set标签中配置cascade属性为save-update

<set name="phones" cascade="save-update">
	<!-- 外键列名,多方中 -->
	<key column="fk_u_id"/>
	<one-to-many class="org.itheima.hibernate.domain.Phone" />
</set>

级联保存针对的是,如果数据操作保存一方的数据时,对多方数据库造成的影响。

//创建一方持久化对象
User user = new User();
user.setName("张三");
user.setAge(10);
session.save(user);
// 创建多方持久化对象
Phone p1 = new Phone();
p1.setP_number("13512345678");
// 建立一方和多方的关系
user.getPhones().add(p1);

注意:

  • 不配置级联保存和更新,非持久化状态的多方数据将无法保存成功,需要单独的去操作多方表。
  • 配置了级联保存和更新,非持久化状态的多方数据可以保存成功。

级联更新针对的是,如果数据操作为一方数据再次关联新的多方数据时,对多方数据库造成的影响。

//获得一方的持久化对象
User user = session.get(User.class, 1);
Set<Phone> phones = user.getPhones();
//创建多方的持久化对象
Phone phone = new Phone();
phone.setP_number("8888888");
//建立一方和多方的关系
phones.add(phone);

注意:

  • 不配置级联保存和更新,再次关联新的多方数据将无法保存到多方表中,需要单独的去操作多方表。
  • 配置了级联保存和更新,再次关联新的多方数据会自动保存到多方表中

级联删除

在一方的映射文件中set标签中配置cascade属性为delete

<set name="phones" cascade="delete">
	<!-- 外键列名,多方中 -->
	<key column="fk_u_id"/>
	<one-to-many class="org.itheima.hibernate.domain.Phone" />
</set>

级联删除针对的是 如果数据操作将一方的数据删除,对多方的数据造成的影响。

//user为一方表,phone为多方表,删除user时,对phone表造成怎样的影响
User user = session.get(User.class, 1);
session.delete(user);

注意:

  • 非级联删除只会删除一方数据库表中的记录,不会删除多方表中的记录,只是多方表中记录的外键设置为空
  • 级联删除既会删除一方数据库表中的记录,也会删除多方表中的记录
  • 开发过程中不会有任何删除操作

孤儿删除

在一方的映射文件中set标签中配置cascade属性为delete-orphan

<set name="phones" cascade="delete-orphan">
	<!-- 外键列名,多方中 -->
	<key column="fk_u_id"/>
	<one-to-many class="org.itheima.hibernate.domain.Phone" />
</set>

孤儿删除针对的是 一方和多方间关系解除时,对多方数据造成的影响

//user为一方表,phone为多方表,user和phone关系解除时,对phone表造成怎样的影响
User user = session.get(User.class, 1);
Phone phone = session.get(Phone.class, 1);
user.getPhones().remove(phone);

注意:

  • 非孤儿删除,不会删除多方数据,只会将多方表中的外键设置为空
  • 孤儿删除会删除多方数据库表中的记录
  • 开发过程中不会有任何删除操作

外键维护

概念

inverse:外键维护,默认为false。代表一方不去维护多方外键。(inverse有反转的意思)

  • true:一方不去维护多方外键操作
  • false: 一方去维护多方外键操作
  • 外键维护针对的是具有外键关联的主键表而言的

一方的放弃外键维护

<set name="phones" inverse="true">
	<!-- 外键列名,多方中 -->
	<key column="u_id"/>
	<one-to-many class="org.itheima.hibernate.domain.Phone" />
</set>

多方的级联操作

级联保存和修改

在多方的映射文件中many-to-one标签中配置cascade属性为save-update

<many-to-one 
	name="user" 
	class="org.itheima.hibernate.domain.User"
	column="u_id" 
	cascade="save-update" />

级联保存针对的是,如果数据操作保存多方的数据时,对一方数据库造成的影响。

//创建多方持久化对象
Phone phone = new Phone();			
phone.setP_number("13512345678");
//保存多方持久化对象
session.save(phone);
//创建一方持久化对象
User user = new User();
user.setName("张三疯");
user.setAge(100);
//建立关系
phone.setUser(user);

注意

  • 不配置级联保存和更新,非持久化状态的一方数据将无法保存成功,需要单独的去操作一方表。
  • 配置了级联保存和更新,非持久化状态的一方数据可以保存成功。

级联更新针对的是,如果数据操作为多方数据再次关联新的一方数据时,对一方数据库造成的影响。

//获得多方持久化对象
Phone phone = session.get(Phone.class, 1);
//创建新的一方持久化对象
User user = new User();
user.setName("张天宝");
user.setAge(10);
//建立关系
phone.setUser(user);

注意

  • 不配置级联保存和更新,再次关联新的一方数据将无法保存到一方表中,需要单独的去操作多方表。
  • 配置了级联保存和更新,再次关联新的一方数据会自动保存到一方表中

级联删除

在多方的映射文件中many-to-one标签中配置cascade属性为delete

<many-to-one 
	name="user" 
	class="org.itheima.hibernate.domain.User"
	column="u_id" 
	cascade="delete" />

注意:

  • 多方的级联删除并不是把一方的数据删除,清除的是自己的数据
  • 级联删除并不会删除多方数据库表中的记录,只是将此记录的外键设置为空
  • 开发过程中不会有任何删除操作

多对多的关系

概念

多对多关系是关系数据库中两个表之间的一种数据关系,为了维护这种关系,通常会存在一张中间关系表。两张表都只和关系表间建立主外键关系。

关键字:关系表,主外键关系

数据库方式建立多对多模型

-- 学生表
CREATE TABLE t_student (
	s_id INTEGER NOT NULL AUTO_INCREMENT,
	s_name VARCHAR(255),
	s_age VARCHAR(255),
	PRIMARY KEY (S_ID)
);
-- 教师表
CREATE TABLE t_teacher (
	t_id INTEGER NOT NULL AUTO_INCREMENT,
	t_name VARCHAR(255),
	t_age INTEGER,
	PRIMARY KEY (t_id)
);
-- 关系表
CREATE TABLE r_student_teacher (
	st_id INT PRIMARY KEY AUTO_INCREMENT,
	fk_s_id INTEGER,
	fk_t_id INTEGER
);
-- 教师表和关系表的主外键关系
ALTER TABLE r_student_teacher 
ADD CONSTRAINT fk_teacher FOREIGN KEY (fk_t_id) REFERENCES t_teacher (t_id);
-- 学生表和关系表的主外键关系
ALTER TABLE r_student_teacher 
ADD CONSTRAINT fk_student FOREIGN KEY (fk_s_id) REFERENCES t_student (s_id);

代码生成多对多模型步骤

  1. 导入Hibernate框架的Jar
  2. 新建表结构对应的持久化类:无需为中间关系表创建持久化类
  3. 配置映射文件
  4. 关系结构描述
  5. 配置hibernate启动文件
  6. 通过代码生成表结构

结构描述

持久化类中的描述

Student类中描述teachers

//通过set集合描述 多对多的关系
private Set<Teacher> teachers = new HashSet<>();

Teacher类中描述students

//通过set集合描述 多对多的关系
private Set<Student> students = new HashSet<>();

映射文件的描述

Student映射中描述teachers

<set name="teachers" table="r_student_teacher">
	<key column="fk_s_id" />
	<many-to-many class="org.itheima.hibernate.domain.Teacher"
		column="fk_t_id" />
</set>

Teacher映射中描述students

<set name="students" table="r_student_teacher">
	<key column="fk_t_id" />
	<many-to-many class="org.itheima.hibernate.domain.Student" 
		column="fk_s_id" />
</set>
  • set标签用来描述多的关系
  • set标签中name属性对应中类中描述多的关系的属性名称
  • set标签中table属性对应中多对多的中间关系表的表名
  • key标签是用来维护外键的
  • key标签中的column属性指的是当前对应的表的主键,在中间关系表中对应的外键的名称
  • many-to-many标签是用来描述多对多的关系
  • many-to-many标签中class属性指的是对应多的类的全名称。
  • many-to-many标签中column属性指的是对应多的表的主键,在中间关系表中对应的外键的名称

级联操作

级联保存和修改

在多方的映射文件中的set标签中配置cascade属性为save-update

<set name="teachers" table="r_student_teacher" cascade="save-update">
	<key column="fk_s_id" />
	<many-to-many class="org.itheima.hibernate.domain.Teacher"
				column="fk_t_id" />
</set>

级联保存针对的是,如果数据操作保存正向多方的数据时,对反向多方数据库造成的影响。

//创建正向多方持久化对象1
Student s1 = new Student();
s1.setS_name("张三");
s1.setS_age(18);
session.save(s1);
//创建正向多方持久化对象2
Student s2 = new Student();
s2.setS_name("李四");
s2.setS_age(28);
session.save(s2);
//创建反向多方持久化对象1
Teacher t1 = new Teacher();
t1.setT_name("王五");
t1.setT_age(70);
//创建反向多方持久化对象2
Teacher t2 = new Teacher();
t2.setT_name("赵六");
t2.setT_age(30);
// 建立关系
s1.getTeachers().add(t1);
s1.getTeachers().add(t2);
s2.getTeachers().add(t1);
s2.getTeachers().add(t2);

注意

  • 不配置级联保存和更新,非持久化状态的反向多方数据将无法保存成功,需要单独的去操作多方表。
  • 配置了级联保存和更新,非持久化状态的反向多方数据可以保存成功,保存到反向多方表和中间关系表中。

级联更新针对的是,如果数据操作为正向多方数据再次关联新的反向多方数据时,对反向多方数据库造成的影响。

//获得正向多方持久化对象
Student s = session.get(Student.class, 1);
//创建新的反向多方持久化对象
Teacher t = new Teacher();
t.setT_name("teacher");
t.setT_age(100);
//更新数据
s.getTeachers().add(t);

注意

  • 不配置级联保存和更新,再次关联新的反向多方数据将无法保存到正向多方表中,需要单独的去操作多方表。
  • 配置了级联保存和更新,再次关联新的反向多方数据会自动保存到反向多方表和中间关系表中

级联删除

在多方的映射文件中的set标签中配置cascade属性为delete

<set name="teachers" table="r_student_teacher" cascade="delete">
	<key column="fk_s_id" />
	<many-to-many class="org.itheima.hibernate.domain.Teacher"
				column="fk_t_id" />
</set>

级联删除针对的是 如果数据操作将正向多方表的数据删除,对反向多方表和中间关系表的数据造成的影响。

//获得正向多方的持久化对象
Student s = session.get(Student.class, 1);
session.delete(s);

注意

  • 非级联删除只会删除正向多方数据库表和中间关系表中的记录,不会删除反向多方表中的记录
  • 级联删除既会删除正向多方数据库表中的记录,也会删除反向多方表中的记录和中间关系表中的记录
  • 开发过程中不会有任何删除操作

© 著作权归作者所有

共有 人打赏支持
勤劳的开发者px
粉丝 3
博文 54
码字总数 108225
作品 0
荆州
程序员
SSH

错误信息: 三月 12, 2017 7:19:03 下午 org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions WARN: SQL Error: 1017, SQLState: 72000 三月 12, 2017 7:19:03 下午 org.hibern......

zyx0906840143
2017/03/12
56
2
mysql 整合JBPM 时,部署XML成功,但无法部署zip文件 就是Hibernate保存图片到Mysql数据库的配置问题

mysql 整合JBPM 时,部署XML成功,但无法部署zip文件 最近学习了JBPM,整合到Jeecms框架中,单独发布XML文件成功,但加上图片就不行了 applicationContext.xml 文件关于 Hibernate的配置 hi...

Run佳
2013/03/10
742
2
Dorado7 Hibernate AddOn

Dorado7 Hibernate AddOn 什么是Dorado7 Hibernate Addon? 定位 Dorado7 Hibernate AddOn是Dorado7针对Hibernate提供的整合接口,属于Dorado7 AddOn的一种,是Dorado7自定义扩展的一个实现范...

thinkingdo
2012/05/24
0
0
使用Myeclipse完成Hibernate的逆向工程问题

使用win7 64位系统 myeclipse10, mysql :mysql-5.5.34-winx64.msi , jdk1.7 初学hibernate jdbc驱动:mysql-connector-java-5.1.22-bin.jar 使用myeclipse 完成hibernate reverse engineering......

xinxiwu
2014/03/25
1K
1
struts2+hibernate+spring写的图书管理系统有点小问题,有人帮忙看一下报什么错吗?

信息: Initializing Spring root WebApplicationContext 2015-11-24 17:23:58,739 INFO [org.springframework.web.context.ContextLoader] - 2015-11-24 17:23:58,998 INFO [org.springframe......

梁俊燃
2015/11/24
389
3
javaEE的eclipse安装hibernate插件

在javaEE的eclipse如何安装hibernate插件?网上很多是在线安装或者是在线选择压缩包来安装。但是,很多时候会发现在线安装都不能成功。现在介绍一个简单有效的安装方式。 http://tools.jboss...

一梦心草
2016/04/06
73
0
针对 SaaS 应用程序的基于 Hibernate 框架的数据库分片

简介: 扩展共享数据库的一个最简单的技术是基于租户 ID 通过数据分片启用多租户数据架构。在本文中,我们探究如何使用 Hibernate 分片来解决 SaaS 应用程序的数据库伸缩问题。 针对 SaaS 应...

红薯
2010/11/02
1K
2
Hibernate之HQL查询的一些例子

  Hibernate配备了一种非常强大的查询语言,就是HQL(hibernate query language),HQL看上去很像sql,但只是语法结构上相似,HQL是一种面向对象的查询,他可以理解继承,多态之类的概念.   HQL...

冬至饮雪
2016/03/06
0
0
hibernate4 配合分布式缓存memcache的痛苦配置

hibernate最强大的莫过于缓存功能,配上分布式的memcache应该性能飞快,结果各种麻烦 基本配置网上都有,就不说了 hibernate3缓存的配置 <prop key="hibernate.cache.provider_class">com.g...

程序猿_哲
2014/03/25
0
1
Hibernate 并非一无是处

最近挺长一段时间,有很多人会喷 Hibernate,特别是 12306 被曝用 Hibernate 以来,更是喷得厉害。尽管我对“喷”这件事已经完全免疫了,没有兴趣参与,也丝毫不会激发我的一丝斗志,顶多就是...

红薯
2012/10/16
5.2K
28

没有更多内容

加载失败,请刷新页面

加载更多

下一页

实现异步有哪些方法

有哪些方法可以实现异步呢? 方式一:java 线程池 示例: @Test public final void test_ThreadPool() throws InterruptedException { ScheduledThreadPoolExecutor scheduledThre......

黄威
今天
0
0
linux服务器修改mtu值优化cpu

一、jumbo frames 相关 1、什么是jumbo frames Jumbo frames 是指比标准Ethernet Frames长的frame,即比1518/1522 bit大的frames,Jumbo frame的大小是每个设备厂商规定的,不属于IEEE标准;...

六库科技
今天
0
0
牛客网刷题

1. 二维数组中的查找(难度:易) 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入...

大不了敲一辈子代码
今天
0
0
linux系统的任务计划、服务管理

linux任务计划cron 在linux下,有时候要在我们不在的时候执行一项命令,或启动一个脚本,可以使用任务计划cron功能。 任务计划要用crontab命令完成 选项: -u 指定某个用户,不加-u表示当前用...

黄昏残影
昨天
0
0
设计模式:单例模式

单例模式的定义是确保某个类在任何情况下都只有一个实例,并且需要提供一个全局的访问点供调用者访问该实例的一种模式。 实现以上模式基于以下必须遵守的两点: 1.构造方法私有化 2.提供一个...

人觉非常君
昨天
0
0
《Linux Perf Master》Edition 0.4 发布

在线阅读:https://riboseyim.gitbook.io/perf 在线阅读:https://www.gitbook.com/book/riboseyim/linux-perf-master/details 百度网盘【pdf、mobi、ePub】:https://pan.baidu.com/s/1C20T......

RiboseYim
昨天
1
0
conda 换源

https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/conda config --add channels https://mir......

阿豪boy
昨天
1
0
Confluence 6 安装补丁类文件

Atlassian 支持或者 Atlassian 缺陷修复小组可能针对有一些关键问题会提供补丁来解决这些问题,但是这些问题还没有放到下一个更新版本中。这些问题将会使用 Class 类文件同时在官方 Jira bug...

honeymose
昨天
0
0
非常实用的IDEA插件之总结

1、Alibaba Java Coding Guidelines 经过247天的持续研发,阿里巴巴于10月14日在杭州云栖大会上,正式发布众所期待的《阿里巴巴Java开发规约》扫描插件!该插件由阿里巴巴P3C项目组研发。P3C...

Gibbons
昨天
1
0
Tomcat介绍,安装jdk,安装tomcat,配置Tomcat监听80端口

Tomcat介绍 Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由Apache、Sun和其他一些公司及个人共同开发而成。 java程序写的网站用tomcat+jdk来运行...

TaoXu
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部