Hibernate 一对多/多对多
一对多关联(多对一):
一对多关联映射:
在多的一端添加一个外键指向一的一端,它维护的关系是一指向多
多对一关联映射:
咋多的一端加入一个外键指向一的一端,它维护的关系是多指向一
在配置文件中添加:
在一一端使用<set><key></key><one-to-many></one-to-many></set>
<key>指定的外键字段必须和<many-to-one>指定的外键字段一致
在多一端使用<many-to-one>
在有外键的一端设置many-to-one
数据库中customer表和order表的关系:

创建实体类:
public class Customer {
private Integer id;
private String name;
private Character gender;
private Integer age;
private String level;
//一对多
private Set<Order> orders = new HashSet<Order>();
public Customer() {
super();
}
getters and setters
}
public class Order {
private Integer id;
private String orderno;
private String productName;
//多对一
private Customer customer;
public Order() {
super();
// TODO Auto-generated constructor stub
}
getters and setters
}
创建映射文件:
<hibernate-mapping>
<class name="com.roxy.hibernate.pojo.Customer" table="t_customer"> <id name="id" column="c_id">
<generator class="native"></generator>
</id> <property name="name" column="c_name" not-null="true"></property>
<property name="gender" column="c_gender" length="1"></property>
<property name="age" column="c_age"></property>
<property name="level" column="c_level" length="20"></property> <set name="orders">
<key column="customer_id"></key>
<one-to-many class="com.roxy.hibernate.pojo.Order"/>
</set>
</class>
</hibernate-mapping>
<hibernate-mapping package="com.roxy.hibernate.pojo">
<!-- 类和表的映射 -->
<class name="Order" table="t_order">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<!-- 其他属性映射 -->
<property name="orderno" column="orderno" length="20"></property>
<property name="productName" column="product_name" length="100"></property>
<!-- 多对一 -->
<many-to-one name="customer" class="Customer" column="customer_id" />
</class>
</hibernate-mapping>
创建配置文件:
<!-- mapping文件 -->
<mapping resource="com/roxy/hibernate/pojo/Customer.hbm.xml"/>
<mapping resource="com/roxy/hibernate/pojo/Order.hbm.xml"/>
查看并分析SQL语句:
Hibernate:
alter table t_order
add constraint FKesy3n2gc3fa0s3trrk3tvyv9a
foreign key (customer_id)
references t_customer (c_id) ----- hibernate首先为t_order和t_customer添加外键关联
Hibernate:
insert
into
t_customer
(c_name, c_gender, c_age, c_level)
values
(?, ?, ?, ?) ----- 向t_customer中插入数据(session.save(cust);)
Hibernate:
insert
into
t_order
(orderno, product_name, customer_id)
values
(?, ?, ?) ----- 向t_order中插入数据(session.save(o1);)
----- 此时customer_id为null
Hibernate:
insert
into
t_order
(orderno, product_name, customer_id)
values
(?, ?, ?)
----- 向t_order中插入数据(session.save(o2);)
----- 此时customer_id为null
Hibernate:
update
t_order
set
customer_id=?
where
id=? ----- 维护两个表之间的关系,hibernate更新t_customer数据
Hibernate:
update
t_order
set
customer_id=?
where
id=?
----- 维护两个表之间的关系,hibernate更新t_customer数据
多对多级联:
双向一对多关联就是多对多关联
自动生成一个关联表放置两个表的外键,即联合主键
<!-- 多对多映射 -->
<!-- table:中间表名 -->
<set name="users" table="t_user_role" cascade="save-update">
<!-- 当前方在中间表的外键 -->
<key column="role_id"/>
<!-- column:对方在中间表的外键 -->
<many-to-many class="User" column="user_id"/>
</set>
数据库中user表和role表的关系:

创建实体类:
public class User {
private Integer id;
private String name;
//关联角色
private Set<Role> roles = new HashSet<Role>();
public User() {
super();
// TODO Auto-generated constructor stub
}
}
public class Role {
private Integer id;
private String name;
//关联用户
private Set<User> users = new HashSet<User>();
public Role() {
super();
// TODO Auto-generated constructor stub
}
}
创建映射文件:
User:
<set name="roles" table="t_user_role" >
<!-- 当前方在中间表的外键 -->
<key column="user_id"/>
<!-- column:对方在中间表的外键 -->
<many-to-many class="Role" column="role_id"/>
</set>
Role:
<set name="users" table="t_user_role" >
<!-- 当前方在中间表的外键 -->
<key column="role_id"/>
<!-- column:对方在中间表的外键 -->
<many-to-many class="User" column="user_id"/>
</set>
创建配置文件:
<mapping resource="com/roxy/hibernate/pojo/User.hbm.xml" />
<mapping resource="com/roxy/hibernate/pojo/Role.hbm.xml" />
查看并分析SQL语句:
Hibernate:
insert
into
t_user
(name)
values
(?)
Hibernate:
insert
into
t_role
(name)
values
(?)
Hibernate:
insert
into
t_user_role
(user_id, role_id)
values
(?, ?)
Hibernate:
insert
into
t_user_role
(role_id, user_id)
values
(?, ?) ----- 虽然在test中只保存了user,但是在两个表的映射文件中都对彼此的关联关系进行维护,体现在SQL语句上就是执行了两次t_user_role的插入操作,这就导致了重复插入,报告联合主键重复的异常
解决方法:
1 既然两个表同时维护关联导致异常,那么只要一个表放弃维护即可,使用inverse:
<set name="users" table="t_user_role" inverse="true">
2 在一个表中设置关联保存,在执行test的时候只对此表进行save操作:
<set name="users" table="t_user_role" cascade="save-update">
Hibernate 一对多/多对多的更多相关文章
- Hibernate一对多(多对一)关联关系
上一篇博文总结了 Hibernate 的一对一的关联关系, 包括基于主键的单向一对一, 基于外键的单向一对一, 基于外键的双向一对一. 下面咱们说一下 Hibernate 的一对多关联关系. 其实一对 ...
- hibernate一对多多对一双向
注意事项:一对多,多对一双向关联,在一的一方的多的getSet集合上的oneToMany上加上mappedBy.告诉hibernate由多的方一来维护关系.这也符合逻辑 ,本来外键就是在加在多的一方. ...
- hibernate 一对多 多对一 关系表 增删改查大礼包ps二级查也有
今天来到混元气功 这货大概的意思就是你中有我 我中有你 ps 这里就要说到维护关系 ps写这个用了我一下午.......也是刚刚好复习到这里 顺便就写写 注意:一般都在多方维护关系,至于是用单向还是用 ...
- Hibernate 集合映射 一对多多对一 inverse属性 + cascade级联属性 多对多 一对一 关系映射
1 . 集合映射 需求:购物商城,用户有多个地址. // javabean设计 // javabean设计 public class User { private int userId; privat ...
- Hibernate一对多自关联、多对多关联
今天分享hibernate框架的两个关联关系 多对多关系注意事项 一定要定义一个主控方 多对多删除 主控方直接删除 被控方先通过主控方解除多对多关系,再删除被控方 禁用级联删除 关联关系编辑,不 ...
- Java进阶知识10 Hibernate一对多_多对一双向关联(Annotation+XML实现)
本文知识点(目录): 1.Annotation 注解版(只是测试建表) 2.XML版 的实现(只是测试建表) 3.附录(Annotation 注解版CRUD操作)[注解版有个问题:插入值时 ...
- Hibernate关联映射(一对多/多对多)
版权声明:翀版 https://blog.csdn.net/biggerchong/article/details/843401053. Hibernate关联映射上接Hibernate持久化类:h ...
- 2018.11.4 Hibernate中一对、多对多的关系
简单总结一下 多表关系 一对多/多对一 O 对象 一的一方使用集合. 多的一方直接引用一的一方. R 关系型数据库 多的一方使用外键引用一的一方主键. M 映射文件 一: 多: 操作: 操作管理级别属 ...
- hibernate 一对多双向关联 详解
一.解析: 1. 一对多双向关联也就是说,在加载班级时,能够知道这个班级所有的学生. 同时,在加载学生时,也能够知道这个学生所在的班级. 2.我们知道,一对多关联映射和多对一关联映射是一样的,都是在 ...
随机推荐
- php and mysql 常用api函数
- python打包成.exe
pyuic5 mainwindow.ui -o test.py pip install pyinstaller pyinstaller -F -w ***.py https://blog.csdn.n ...
- git stash,git cherry-pick
git stash: 备份当前的工作区的内容,从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致.同时,将当前的工作区内容保存到Git栈中.git stash pop: 从Git栈中读取 ...
- 【转】WinForm基础
winform基础 先修基础:C#语法基础和面向对象编程 1.Winform创建解决方案 2.Winform窗体 3.MessageBOx 4.Winform登录.控制软件只运行一次.回车登录 5.W ...
- [LeetCode&Python] Problem 884. Uncommon Words from Two Sentences
We are given two sentences A and B. (A sentence is a string of space separated words. Each word co ...
- LeetCode-Microsoft-Add Two Numbers II
You are given two non-empty linked lists representing two non-negative integers. The most significan ...
- Django的DateTimeField和DateField
一.DateField: class DateField(auto_now=False, auto_now_add=False, **options)[source] auto_now:每次保存时,都 ...
- arm交叉编译器gnueabi、none-eabi、arm-eabi、gnueabihf等的区别
博客来之于: http://www.veryarm.com/296.html 命名规则: 交叉编译工具链的命名规则为:arch [-vendor] [-os] [-(gnu)eabi] arch - ...
- 虚拟机CentOS的NAT模式联网和SecureCRT远程登录管理工具
Cenos7 发生了很大的变化,不过也是直接配置网络,从启网卡,从启机器,crt链接 https://blog.csdn.net/gebitan505/article/details/54584213 ...
- Linux内核中的机制学习总结
一.驱动中的poll机制 1.简介:select()和poll()系统调用的本质一样,前者在 BSD UNIX 中引入的,后者在 System V 中引入的. 应用程序使用 select() 或 po ...
