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.我们知道,一对多关联映射和多对一关联映射是一样的,都是在 ...
随机推荐
- RSA签名验证无法通过,检查以下部分
RSA签名验证无法通过,检查以下部分:1.是否和上游交换公钥,提交给上游的公钥是否配置正确并生效2.检查加密方式是SHA1还是MD5,是否跟上游一致3.上游采用的是否是base64SafeUrl的方式 ...
- TreeView添加treeView1_NodeMouseClick----多么痛的领悟。。。
TreeView添加treeView1_NodeMouseClick----多么痛的领悟... 1首先说一点,通过参考代码,已经实现了菜单项自动添加到TreeView控件的树视图了. 2.在移植(菜单 ...
- 隔行扫瞄/逐行扫瞄的介绍(Interlaced / Progressive)
隔行扫瞄/逐行扫瞄的介绍(Interlaced / Progressive) 本篇不是着重在理论说明, 而是实际验証结果的分享, 所以只简略解释何谓交错与非交错, 请参考如后. 交错扫瞄(隔行扫瞄 ...
- Foundation--NSString , array and Dictionary
一,NSString的创建 NSString*str=@" a string ";//直接创建一个字符串常量,这样创建出来的字符串不需要释放内存 NSLog(@"%@&q ...
- sed使用笔记
1.在匹配行前后添加内容 i a sed -i -r '/Processrun.sh/a01 00 * * * /data/scripts/nginx/ngx_logcut.sh' /var/spoo ...
- Unity3D插件-自制小插件、简化代码便于使用(新手至高手进阶必经之路)
Unity3D插件-简化代码.封装功能 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 FindT() ...
- t添加最佳视口
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- Laravel学习之旅(三)
视图 一.怎么新建视图: 1.视图默认存放路径:resources/views: 2.laravel模板支持原生的PHP,直接可以在resources/views新建一个PHP文件,例如: index ...
- SQL SERVER 2008R2 执行大脚本文件时,管理工具提示“内存不足”的解决方法
项目需求:当我把服务器上的数据库导出为SQL脚本时,在本地新建数据库,再导入执行SQL文件时报错,因为SQL文件过大,导致出现如下报错 如下图所示: ========================= ...
- 多边形面积问题(hdoj2036)
杭电oj2036http://acm.hdu.edu.cn/showproblem.php?pid=2036 计算几何,求多边形的面积 只要记住这个公式: 如果逆时针给出点坐标,值为正, 如果顺时针给 ...
