008多对一 关联映射 --- many-to-one
- 多对一 --- many-to-one
- 一对多 --- one-to-many
- 一对一 --- one-to-one
- 多对多 --- many-to-many
场景:用户和组;从用户角度来,多个用户属于一个组(多对一 关联)
使用hibernate开发的思路:先建立对象模型(领域模型),把实体抽取出来。
目前两个实体:用户和组两个实体,多个用户属于一个组,那么一个用户都会对应于一个组,所以用户实体中应该有一个持有组的引用。
关联映射的本质:
将关联关系映射到数据库,所谓的关联关系是对象模型在内存中一个或多个引用。
User实体类:
public class User { private int id; private String name; private Group group; public Group getGroup() { return group; } public void setGroup(Group group) { this.group = group; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Group实体类:
public class Group { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
实体类建立完后,开始创建映射文件,先建立简单的映射文件:
Group实体类的映射文件:
<hibernate-mapping> <class name="com.wjt276.hibernate.Group" table="t_group"> <id name="id" column="id"> <generator class="native"/> </id> <property name="name"/> </class> </hibernate-mapping>
User实体类的映射文件:
<hibernate-mapping> <class name="com.wjt276.hibernate.User" table="t_user"> <id name="id" column="id"> <generator class="native"/> </id> <property name="name"/> <!--<many-to-one> 关联映射 多对一的关系 name:是维护的属性(User.group),这样表示在多的一端表里加入一个字段名称为group, 但group与SQL中的关键字重复,所以需要重新命名字段(column="groupid"). 这样这个字段(groupid)会作为外键参照数据库中group表(t_group也叫一的一端),也就是就在多的一 端加入一个外键指向一的一端。 --> <many-to-one name="group" column="groupid"/> </class> </hibernate-mapping>
※<many-to-one>标签※:
例如:<many-to-one name="group" column="groupid"/>
<many-to-one> 关联映射多对一的关系
name:是维护的属性(User.group),这样表示在多的一端表里加入一个字段名称为group,但group与SQL中的关键字重复,所以需要重新命名字段(column="groupid").这样这个字段(groupid)会作为外键参照数据库中group表(t_group也叫一的一端),也就是就在多的一端加入一个外键指向一的一端。
这样导出至数据库会生成下列语句:
alter table t_user drop foreign key FKCB63CCB695B3B5AC drop table if exists t_group drop table if exists t_user create table t_group (id integer not null auto_increment, name varchar(255), primary key (id)) create table t_user (id integer not null auto_increment, name varchar(255), groupid integer, primary key (id)) alter table t_user add index FKCB63CCB695B3B5AC (groupid), add constraint FKCB63CCB695B3B5AC foreign key (groupid) references t_group (id) |
多对一 存储(先存储group(对象持久化状态后,再保存user)):
session = HibernateUtils.getSession(); tx = session.beginTransaction(); Group group = new Group(); group.setName("wjt276"); session.save(group); //存储Group对象。 User user1 = new User(); user1.setName("菜10"); user1.setGroup(group);//设置用户所属的组 User user2 = new User(); user2.setName("容祖儿"); user2.setGroup(group);//设置用户所属的组 //开始存储 session.save(user1);//存储用户 session.save(user2); tx.commit();//提交事务
执行后hibernate执行以下SQL语句:
Hibernate: insert into t_group (name) values (?)
Hibernate: insert into t_user (name, groupid) values (?, ?)
Hibernate: insert into t_user (name, groupid) values (?, ?)
注意:如果上面的session.save(group)不执行,则存储不存储不成功。则抛出TransientObjectException异常。
因为Group为Transient状,Object的id没有分配值。
结果:persistent状态的对象是不能引用Transient状态的对象
以上代码操作,必须首先保存group对象,再保存user对象。我们可以利用cascade(级联)方式,不需要先保存group对象。而是直接保存user对象,这样就可以在存储user之前先把group存储了。
利用cascade属性是解决TransientObjectException异常的一种手段。
重要属性-cascade(级联):
级联的意思是指定两个对象之间的操作联运关系,对一个 对象执行了操作之后,对其指定的级联对象也需要执行相同的操作,取值:all、none、save_update、delete
1、 all:代码在所有的情况下都执行级联操作
2、 none:在所有情况下都不执行级联操作
3、 save-update:在保存和更新的时候执行级联操作
4、 delete:在删除的时候执行级联操作。
例如:<many-to-one name="group" column="groupid" cascade="save-update"/> |
多对一 加载数据
代码如下:
session = HibernateUtils.getSession(); tx = session.beginTransaction(); User user = (User)session.load(User.class, 3); System.out.println("user.name=" + user.getName()); System.out.println("user.group.name=" + user.getGroup().getName()); //提交事务 tx.commit();
执行后向SQL发出以下语句:
Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_, user0_.groupid as groupid0_0_ from t_user user0_ where user0_.id=? Hibernate: select group0_.id as id1_0_, group0_.name as name1_0_ from t_group group0_ where group0_.id=? |
可以加载Group信息:因为采用了<many-to-one>这个标签,这个标签会在多的一端(User)加一个外键,指向一的一端(Group),也就是它维护了从多到一的这种关系,多指向一的关系。当你加载多一端的数据时,它就能把一的这一端数据加载上来。当加载User对象后hibernate会根据User对象中的groupid再来加载Group信息给User对象中的group属性
008多对一 关联映射 --- many-to-one的更多相关文章
- (Hibernate进阶)Hibernate映射——多对多关联映射(八)
多对多映射是现实生活中最常见的映射,也是最容易理解的映射.废话少说,直接开始. 映射原理 不论是单向关联还是双向关联都是通过第三张表,将两个表中的主键放到第三张做一个关联.用第三张表来解决可能会造成数 ...
- Hibernate(六)——多对多关联映射
前面几篇文章已经较讲解了三大种关联映射,多对多映射就非常简单了,不过出于对关联映射完整性的考虑,本文还是会简要介绍下多对多关联映射. 1.单向多对多关联映射 情景:一个用户可以有多个角色,比如数据录入 ...
- hibernate之关于使用连接表实现多对一关联映射
[Hibernate]之关于使用连接表实现多对一关联映射 在我们项目使用中採用中间表最多的一般就是多对一,或者是多对多,当然一对一使用中间表也是能够的,可是这样的几率通常少之又少!所以这里重点介绍多对 ...
- 017 多对多关联映射 双向(many-to-many)
多对多关联映射 双向 两方都持有对象引用,修改对象模型,但数据的存储没有变化. 再修改映射文件: public class Role { private int id; private String ...
- 016 多对多关联映射 单向(many-to-many)
一般的设计中,多对多关联映射,需要一个中间表 Hibernate会自动生成中间表 Hibernate使用many-to-many标签来表示多对多的关联 多对多的关联映射,在实体类中,跟一对多一样,也是 ...
- 一口一口吃掉Hibernate(六)——多对多关联映射
今天来说说hibernate中的多对多关联映射,多对多关联映射涉及到单向映射和双向映射2种. 首先举个多对多关联例子:用户User和角色Role,一个用户可以属于多个角色,一个角色可以有多个用户.这就 ...
- 【SSH系列】Hibernate映射 -- 多对多关联映射
映射原理 在数据库学习阶段,我们知道,如果实体和实体之间的关系是多对多,那么我们就抽出来第三张表,第一张表和第二张表的主键作为第三表的联合主键,结合我们的hibernate,多对多关联,无论 ...
- hibernate的多对多关联映射
在我们实际项目中,多对多的情况也时长存在,比如最常见的就是系统管理的五张表,如下面的一个结构: 在本文学习hibernate多对多关联映射的实验中我简单的写几个字段,达到学习目的即可. 1.多对多的关 ...
- Hibernate ManyToOne Mappings 多对一关联映射
Hibernate ManyToOne Mappings 多对一关联映射 Hibernate框架的使用步骤: 1.创建Hibernate的配置文件(hibernate.cfg.xml)2.创建持久化类 ...
随机推荐
- SpringMVC基础学习(一)—初识SpringMVC
一.HelloWorld 1.导入SpringMVC所需的jar包 2.配置web.xml 配置DispatcherServlet.DispatcherServlet默认加载/ ...
- 关于C++ 循环
有的时分,可能需求屡次履行同一块代码.通常情况下,句子是顺序履行的:函数中的第一个句子先履行,接着是第二个句子,依此类推. 编程言语供给了答应更为杂乱的履行途径的多种操控结构. 循环句子答应咱们屡次履 ...
- day001-html知识点总结(-)块级。行内元素区分
-.行内元素和块级元素的区别与转换: 区别: 1.从形式上看,在标准文档流中,行内元素会水平方向呈线性排列,而块级元素会各占一行,垂着方向排列. 2.在结构使用上,块级元素可以包含行内元素和块级元素, ...
- 使用Docker分分钟启动常用应用
前言 Docker是目前比较火的一个概念,同时也是微服务中比较关键的一个容器化技术.但是,单从理论上好难看出Docker的优势,因此,我希望在这篇文章中提供一些Docker的使用示例,希望从实际应用上 ...
- ES6 Promise 状态解惑
Promise的概念在ES6标准推出来之前已经深入人心,很多框架和第三方库都有类似的实现.但在深入理解ES6的Promise对象的时候,受之前经验的影响,很多概念给人似是而非的感觉,其中有一个特别明显 ...
- 事件驱动的Python实现
EventManager事件管理类实现,大概就百来行代码左右.如果有不了事件驱动的工作原理的可以看前一篇<事件驱动的简明讲解> # encoding: UTF-8 # 系统模块 from ...
- [原创] IAR7.10安装注册教程
代码开发简单化的趋势势不可挡,TI 公司推出的 IAR7.10 以上版本,集成代码库,方便初学者进行学习移植.本教程详细列出IAR7.10安装以及注册步骤,不足之处望多多交流. 好了进入正题. 第一, ...
- .exe简单的更新软件demo
百度网盘源码加文件:http://pan.baidu.com/s/1qYe2Vgg 功能:通过网站更新用户的软件,需要联网,也可以通过本地网站更新局域网用户软件. 根本实现:1.一个网站(本地就可以) ...
- 面试题 ARC
什么是ARC ?ARC主要解决什么问题? ARC:自动引用计数. 要点..当对象被创建时 retain count+1, 当对象被release时 retain count-1, 当retain co ...
- 统计学习方法:核函数(Kernel function)
作者:桂. 时间:2017-04-26 12:17:42 链接:http://www.cnblogs.com/xingshansi/p/6767980.html 前言 之前分析的感知机.主成分分析( ...