------------------------Hibernate一对多OnetoMany
要点:
配置在一端。
1.如果是单向关联,即只在一端配置OneToMany,多端不配置ManyToOne。则会创建一张关系表。
2.如果在单向关联的OneToMany上加上@JoinColumn,则会在多端增加一个外键维护关系,而不单独创建关系表。
3.可以配置级联操作 @OneToMany(cascade=CascadeType.ALL),保存一端的时候保存多端
4.如果是双向关联,即在一端配置OneToMany,多端配置ManyToOne,则在多端增加外键字段维护关系,
并且要使用mappedBy或者是inverse确保只有一端维护关系 2.单向关联
@Entity
public class User { @Id
@GeneratedValue
private long id; @Column(name="name")
private String name; @OneToMany(cascade=CascadeType.ALL)
@JoinColumn
private Set<Role> roles = new HashSet<Role>(); } @Entity
public class Role {
@Id
@GeneratedValue
private long id;
@Column
private String name;
} 执行:
User user = new User();
user.setName("zhangsan"); Role r1= new Role();
r1.setName("ADMIN");
Role r2= new Role();
r2.setName("EDITOR"); user.getRoles().add(r1);
user.getRoles().add(r2); session.save(user); 结果:
Hibernate:
insert
into
User
(name, id)
values
(?, ?)
Hibernate:
insert
into
Role
(name, id)
values
(?, ?)
Hibernate:
insert
into
Role
(name, id)
values
(?, ?)
Hibernate:
update
Role
set
roles_id=?
where
id=?
Hibernate:
update
Role
set
roles_id=?
where
id=?
保存user后保存两个role 然后更新外键。多两条更新语句。 执行:保存user后删除一个role对象。
User user = new User();
user.setName("zhangsan"); Role r1= new Role();
r1.setName("ADMIN");
Role r2= new Role();
r2.setName("EDITOR"); user.getRoles().add(r1);
user.getRoles().add(r2); session.save(user);
user.getRoles().remove(r1);
结果:
Hibernate:
insert
into
User
(name, id)
values
(?, ?)
Hibernate:
insert
into
Role
(name, id)
values
(?, ?)
Hibernate:
insert
into
Role
(name, id)
values
(?, ?)
Hibernate:
update
Role
set
roles_id=?
where
id=? 保存user后保存两个role,然后更新被删除role的外键为Null。此时并没有删除role这个数据。
只需要增加orphanRemoval=true,则会删除已经没有关联关系的子实体
@Entity
public class User { @Id
@GeneratedValue
private long id; @Column(name="name")
private String name; @OneToMany(cascade=CascadeType.ALL,orphanRemoval=true)
@JoinColumn
private Set<Role> roles = new HashSet<Role>();
} 结果:
Hibernate:
insert
into
User
(name, id)
values
(?, ?)
Hibernate:
insert
into
Role
(name, id)
values
(?, ?)
Hibernate:
insert
into
Role
(name, id)
values
(?, ?)
Hibernate:
update
Role
set
roles_id=?
where
id=?
Hibernate:
delete
from
Role
where
id=? 将移除的子实体更新外键为null,然后执行删除,效率一般。 4.双向关联
要点:关系必须双向都设置,业务代码中关系也必须双向设置
mappedBy指向多端实体里的一端变量名
inverse和mappedBy是同一个东西,只是inverse是用于xml配置,而mappedBy则是用于注解中。
只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性; @Entity
public class User { @Id
@GeneratedValue
private long id; @Column(name="name")
private String name; @OneToMany(cascade=CascadeType.ALL,mappedBy="user")//由多端维护关系
private Set<Role> roles = new HashSet<Role>();
} @Entity
public class Role {
@Id
@GeneratedValue
private long id;
@Column
private String name;
@ManyToOne
private User user;
} -------------------mappedBy 只保存一端
T1
执行:
User user = new User();
user.setName("zhangsan"); Role r1= new Role();
r1.setName("ADMIN");
Role r2= new Role();
r2.setName("EDITOR");
//业务代码中双向设置关系
user.getRoles().add(r1);
user.getRoles().add(r2);
r1.setUser(user);
r2.setUser(user); session.save(user);
结果:
Hibernate:
insert
into
User
(name, id)
values
(?, ?)
Hibernate:
insert
into
Role
(name, user_id, id)
values
(?, ?, ?)
Hibernate:
insert
into
Role
(name, user_id, id)
values
(?, ?, ?)
执行3条语句,插入结果正确。将保存操作传递到多端了,然后进行了保存。 --------------------------------mappedBy 先保存多端,再保存一端
User user = new User();
user.setName("zhangsan"); Role r1= new Role();
r1.setName("ADMIN");
Role r2= new Role();
r2.setName("EDITOR"); user.getRoles().add(r1);
user.getRoles().add(r2);
r1.setUser(user);
r2.setUser(user);
session.save(r1);
session.save(r2);
session.save(user);//无此句则报错,因为user为瞬时态,而role端无级联操作
结果:
Hibernate:
insert
into
Role
(name, user_id, id)
values
(?, ?, ?)
Hibernate:
insert
into
Role
(name, user_id, id)
values
(?, ?, ?)
Hibernate:
insert
into
User
(name, id)
values
(?, ?)
Hibernate:
update
Role
set
name=?,
user_id=?
where
id=?
Hibernate:
update
Role
set
name=?,
user_id=?
where
id=?
先保存两个role,然后保存user。role负责关系维护,又更新了关系外键。 ---------------------mappedBy 只保存一端,并删除一端集合的一个数据 执行:
User user = new User();
user.setName("zhangsan"); Role r1= new Role();
r1.setName("ADMIN");
Role r2= new Role();
r2.setName("EDITOR");
//业务代码中双向设置关系
user.getRoles().add(r1);
user.getRoles().add(r2);
r1.setUser(user);
r2.setUser(user); session.save(user);
user.getRoles().remove(r1); 结果:
Hibernate:
insert
into
User
(name, id)
values
(?, ?)
Hibernate:
insert
into
Role
(name, user_id, id)
values
(?, ?, ?)
Hibernate:
insert
into
Role
(name, user_id, id)
values
(?, ?, ?) 没有进行删除操作。User不负责关系维护,操作失败。
当指定orphanRemoval=true时删除成功! ---------级联删除
--------------------直接删除一端(数据为T1操作后的数据)
User user = session.get(User.class, 170l);
session.remove(user); 结果:
Hibernate:
delete
from
Role
where
id=?
Hibernate:
delete
from
Role
where
id=?
Hibernate:
delete
from
User
where
id=?

删除了一端和所有多端。删除进行了级联传递,先删除多端的两个Role,然后删除用户。
此时确先删除了多端,然后删除一端?直接先删除一端是不可能的

--------------------直接删除多端
Role r = session.get(Role.class, 175l);
session.remove(r);
结果:
Hibernate:
delete
from
Role
where
id=?
执行成功。相当于执行了mantoone的删除

//删除
User user = session.get(User.class, 167l);
Role role = session.get(Role.class, 168l);
System.out.println(user.getName());
System.out.println(role.getName());
user.getRoles().remove(role);//当载入内存后,必须解除关系,再删除
session.remove(role);//删除成功

  

Hibernate一对多OnetoMany的更多相关文章

  1. 【Jpa hibernate】一对多@OneToMany,多对一@ManyToOne的使用

    项目中使用实体之间存在一对多@OneToMany,多对一@ManyToOne的映射关系,怎么设置呢? GitHub地址:https://github.com/AngelSXD/myagenorderd ...

  2. hibernate 一对多双向关联 详解

    一.解析: 1.  一对多双向关联也就是说,在加载班级时,能够知道这个班级所有的学生. 同时,在加载学生时,也能够知道这个学生所在的班级. 2.我们知道,一对多关联映射和多对一关联映射是一样的,都是在 ...

  3. Hibernate一对多单向关联和双向关联映射方法及其优缺点 (待续)

    一对多关联映射和多对一关联映射实现的基本原理都是一样的,既是在多的一端加入一个外键指向一的一端外键,而主要的区别就是维护端不同.它们的区别在于维护的关系不同: 一对多关联映射是指在加载一的一端数据的同 ...

  4. Hibernate一对多操作

    --------------------siwuxie095 Hibernate 一对多操作 以客户和联系人为例,客户是一,联系人是多 即 一个客户里面有多个联系人,一个联系人只能属于一个客户 注意: ...

  5. hibernate 一对多(级联关系)

    hibernate 核心配置文件 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hiber ...

  6. Java进阶知识10 Hibernate一对多_多对一双向关联(Annotation+XML实现)

    本文知识点(目录): 1.Annotation 注解版(只是测试建表)    2.XML版 的实现(只是测试建表)    3.附录(Annotation 注解版CRUD操作)[注解版有个问题:插入值时 ...

  7. Java进阶知识09 Hibernate一对多单向关联(Annotation+XML实现)

    1.Annotation 注解版 1.1.在一的一方加Set 1.2.创建Customer类和Order类 package com.shore.model; import java.util.Hash ...

  8. Hibernate一对多配置

    刚刚学习了Hibernate框架的基础知识,下面我来说说关于Hibernate一对多的配置 首先是大配置 连接数据库 用户名 和密码 能和小配置连接 部门小配置: 员工小配置: 部门实体类 员工实体类 ...

  9. JPA总结——实体关系映射(一对多@OneToMany)

    JPA总结——实体关系映射(一对多@OneToMany) 注意:本文出自“阿飞”的博客,如果要转载本文章,请与作者联系! 并注明来源: http://blog.sina.com.cn/s/blog_4 ...

随机推荐

  1. mfs windows客户端

    之前用moosefs,苦于没有Windows客户端, 本来想在Linux上mfsmount一个目录然后用samba做共享目录,但是这样太不简洁了. 当然豆瓣上有的小伙伴也说自己开发了moosefs的W ...

  2. 一次完整的http事务的过程

    1.域名解析 2.发起TCP三次握手 3.建立TCP连接以后发起http请求 4.服务器端响应请求,浏览器得到html代码 5.浏览器解析html代码并请求html中的资源 6.浏览器对页面进行渲染呈 ...

  3. Android 音视频深入 十一 FFmpeg和AudioTrack播放声音(附源码下载)

    项目地址,求starhttps://github.com/979451341/AudioVideoStudyCodeTwo/tree/master/FFmpeg%E6%92%AD%E6%94%BE%E ...

  4. Linux内核分析--理解进程调度时机、跟踪分析进程调度和进程切换的过程

    ID:fuchen1994 姓名:江军 作业要求: 理解Linux系统中进程调度的时机,可以在内核代码中搜索schedule()函数,看都是哪里调用了schedule(),判断我们课程内容中的总结是否 ...

  5. 50个常用的Linux命令(三)awk

    [root@localhost cee]# echo -e "line1\nline2"|awk '{ print }'line1line2[root@localhost cee] ...

  6. Java容器解析系列(1) 迭代的进化——从Enumeration到Iterator

    在Java中,对于所有的Collection,都有一个特性,可以通过迭代器来遍历和删除其中的元素,因为Collection接口继承自Iterable接口. public interface Colle ...

  7. 关于数据安全RSA,MD5,TOKEN

    网络上明文传输时 1.数据可能被窃取:2.数据可能被篡改:3.数据被泄露 如何解决: 1.数据被窃取是由于数据能随意的被拿到,且能够被识别.可以有2个方式解决 a.使数据不能随意被获取: 使用toke ...

  8. Java log4j

    <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging& ...

  9. L2-013. 红色警报(并查集)*

    L2-013. 红色警报 参考博客 #include <cstdio> #include <algorithm> #include <iostream> #incl ...

  10. 创建cocoapod静态库发布到网上使用

    1,在github上创建一个空仓库,要有licence和readme,clone到本地 2,pod lib create 项目名,这样就创建了一个静态库 3,pod spec create 项目名,创 ...