首页 > 其他分享 >hibernate——一对一、多对一和多对多关系的比较

hibernate——一对一、多对一和多对多关系的比较

时间:2023-08-27 11:02:06浏览次数:49  
标签:hibernate student 映射 一对一 关联 teacher KEY id 比较


现在学习完了这几种映射关系,但是有点乱,这里来小结一下。关键是表之间如何产生映射关系,以及产生的表的结构。

1、一对一映射:

一对一是通过one-to-one标签来产生映射关系的,其实,如果单单说是建立两个表之间的关联,只要在一个映射文件中配置one-to-one标签就可以了,在另一个映射文件中,也做类似的配置,只会起到关联的作用,建立起双向的关联。这里举Person和IdCard的例子,IdCard类的映射文件如下:

<class name="IdCard" table="id_card">
		<id name="id">
		      <generator class="native"></generator>
		</id>
		<property name="No"/>
		<one-to-one name="person" constrained="true"/>
</class>

constrained="true"指定了将person表的主键设置为id_card表的外键,这样就建立起了两个表的关联,若不指定,两个表就是孤立的,互相没有关系。

建立表的ddl语句如下:

CREATE TABLE `id_card` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `No` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FK627C1FB4AEED3EC` (`id`),
  CONSTRAINT `FK627C1FB4AEED3EC` FOREIGN KEY (`id`) REFERENCES `person` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=gbk

在Person类的映射文件中可以不指定one-to-one标签,但那样建立起来的是单向的映射关系,即从id_card表可以映射到person表,但是反之就不行。这在通过person表查询id_card表时,不能查询。如果要让person关联到id_card那么就要在Person类的映射文件中,也配置一下one-to-one标签了。


2、多对一映射:

建立两个表的映射的关系,都是通过建立外键来关联的,多对一也不例外,例如员工和部门的关系属于多对一的关系,多个员工属于同一个部门,所以在部门类中要有一个员工的集合属性。要实现双向映射的话,还必须在员工类中有部门的属性。如果单单建立两个表之间的关联,也像一对一一样,只需要在一个映射文件中配置就可以了,但是,多对一的映射文件的配置不像一对一那样简单,相对复杂的是在“一”这个角色,不是只使用一个<one-to-many>就可以了的,看下面这个配置“一”角色的例子:

部门类的映射文件:
<class name="Department">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		
		<set name="emps">
			<key column="depart_id"/><!-- key指明了员工表中的外键,column为这外键重命名列名-->
			<one-to-many class="Employee"/><!-- one-to-many指明了和哪个类进行一对多的映射 -->
		</set>
</class>

它是配置了一个set标签,在标签中指定了要关联的类和在要关联类中的外键。“一”这一方是通过这种方式建立和“多”的关联的。那么,要是用“多”那一方怎么建立关联呢?看下例:

员工类的映射文件:
<class name="Employee">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<many-to-one name="depart" column="depart_id"></many-to-one>
		<!-- many-to-one指明了外键 ,会根据反射机制,找到要和Employee建立多对一关系的类-->
</class>

使用<many-to-one>标签也可以建立起和部门表的关联,而且这种方式要简洁很多。不管用哪种方式建立关联,所得的数据库的结果是一样的,如本例中,建立的员工表的ddl语句为:

CREATE TABLE `employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `depart_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FK4AFD4ACE972E0614` (`depart_id`),
  CONSTRAINT `FK4AFD4ACE972E0614` FOREIGN KEY (`depart_id`) REFERENCES `department` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=gbk




3、多对多映射:

因为是多对多的关系,只用两个表是无法表示这种关系的,所以建立出来第三方表,只保存这两个表之间的关系,这样就把多对多映射转换成了两个多对一映射。如果单单是建立两个表之间的关联,和上两种情况一样,只需要在其中一个映射文件中配置即可,但是要建立双向映射的话,就要在两个映射文件中都配置关联了。

这里我们举老师和学生的例子,他们的映射文件分别如下:

<class name="Teacher">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<set name="students" table="teacher_student">
			<key column="teacher_id"/>
			<many-to-many class="Student" column="student_id"/>
		</set>
</class>
<class name="Student">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<set name="teachers" table="teacher_student">
			<key column="student_id"/>
			<many-to-many class="Teacher" column="teacher_id"/>
		</set>
</class>

是不是看起来和多对一的映射文件有些类似?但是,不同的是,这里出现了第三个表:teacher_student,表中只有两列:teacher_id和student_id,并且分别是teacher和student表的外键,建立的teacher_student表就是老师和学生表之间的关联,其建立的ddl语句为:

CREATE TABLE `teacher_student` (
  `teacher_id` int(11) NOT NULL,
  `student_id` int(11) NOT NULL,
  PRIMARY KEY (`student_id`,`teacher_id`),
  KEY `FK2E2EF2DEDE6A927E` (`teacher_id`),
  KEY `FK2E2EF2DECDCF47DE` (`student_id`),
  CONSTRAINT `FK2E2EF2DECDCF47DE` FOREIGN KEY (`student_id`) REFERENCES `student` (`id`),
  CONSTRAINT `FK2E2EF2DEDE6A927E` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk




通过上面的总结,应该清楚以下几个问题:

1、如果说单单建立两个表之间的关联,在其中一个映射文件中配置关联就可以了,就能够在数据库中生成外键,建立关联。

2、虽说在一个映射文件中就可以建立两个表的关联,但是不同的映射关系在不同的映射文件中,配置的方法是不同的。

3、若要建立双向的关联的话,就要在两个映射文件中都进行关联配置。


标签:hibernate,student,映射,一对一,关联,teacher,KEY,id,比较
From: https://blog.51cto.com/u_5173797/7251471

相关文章

  • openresty中几种重定向的差异比较(ngx.redirect、ngx.req.set_uri、ngx.exec)
    一.测试用的nginx.conf: userroot;worker_processes1;error_loglogs/error.log;events{worker_connections1024;}http{charsetutf-8;default_typeapplication/octet-stream; include/usr/local/openresty/nginx/conf/mime.typ......
  • 生信:RNA-Seq 比对工具性能比较 [STAR、Tophat2、HISAT2]
    RNA-Seq比对工具性能比较参考文章:https://yanzhongsino.github.io/2021/11/19/omics_transcriptome.RNA-seq/https://www.biostars.org/p/288726/比对(align)介绍序列比对又称为alignRNA-Seq分析中的策略从文件类型来看如下:graphLRFASTQ文件----->SAM文件-----......
  • 期货公司开户手续费哪家比较低?
    同一家公司不同客户之间的手续费会有很大差别,为什么呢?除了资金量有关系外最主要的原因是开户方式,不管哪家公司,如果你直接到柜台去开户,或者直接在官网开户,那手续费都会比较高,但如果你是与期货公司客户经理谈好价格再开户,那手续费变动就很大了,只要你会谈,大部分公司都是可以做到加1分......
  • js不区分大小写比较字符串|字符串转小写
    toLowerCase()方法用于把字符串转换为小写,在做字符串比较不区分大小写的时候用此方法,效果:代码://不区分大小写Stringstr=‘ABC’if(‘abc’==str.toLowerCase()){return“1”;//正确}else{return“0”;//错误}}toUpperCase():字符串转大写,比较同上......
  • HelpLook 免费版与商业版的比较,帮助您快速选择!
    HelpLook 是一款零代码、开箱即用的帮助中心及博客网站搭建工具,只需简单几步,即可帮助企业、机构、个人发布在线品牌内容站点。HelpLook 提供多个版本方案供不同需求的用户选择,今天想着重跟大家分享免费版和商业版,将从三个方面为大家讲解版本之间的区别:✔  版本使用量对比✔  ......
  • QPrinter构造比较慢怎么办
    在Qt中,QPrinter构造比较慢可能是因为它需要查询系统上可用的打印机列表。如果系统中有很多打印机或者网络环境不好,这个过程可能会比较耗时。一种解决方法是将QPrinter的构造延迟到需要使用时再进行。例如,在用户点击“打印”按钮之前,我们不需要创建QPrinter对象。当用户点击“打印......
  • Spring Data JPA查询报错java.lang.StackOverflowError hibernate SpringBoot
    toString()造成死循环,重写toString()方法现象测试JPA的多对多查询时,有一个User对象,该User有多个Role,然后报错User@Data@Entity@Table(name="user")publicclassUser{@Id//主键自动增长@GeneratedValue(strategy=GenerationType.IDENTITY)@Co......
  • 精选论文翻译 | MIMO雷达波形的分析与比较
    本文编辑:@调皮连续波,保持关注调皮哥,获得更多雷达学习资料和建议!大家好,我是调皮哥,今天继续给大家分享干货,助力大家轻松、快乐、有方向地学习雷达。雷达的理论很丰富,可谓博大精深。关于基础部分知识,除了有些是我没有研究过不会之外,可以总结以及我个人能够总结的东西其实差不多都吐完......
  • Kubernetes、Docker Swarm和Rancher的特点 - 容器编排平台比较
    本文将介绍三种流行的容器编排平台:Kubernetes、DockerSwarm和Rancher。我们将比较它们的特点,包括架构、功能、性能和生态系统。通过了解这些平台的优势和劣势,读者可以更好地选择适合自己需求的容器编排平台。引言随着容器技术的快速发展,容器编排平台的需求也日益增长。容器编排......
  • hibernate_demo
    参考:ORM----hibernate入门Demo(无敌详细版)-Old-凯-博客园(cnblogs.com)Hibernate-基础入门详解_51CTO博客_hibernate入门hmb.xml:Hibernate框架之hbm.xml映射文件(详解)_hibernate映射文件详解_hestyle的博客-CSDN博客 新建testdb数据库,创建tb_users表: 模块整体目录......