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.我们知道,一对多关联映射和多对一关联映射是一样的,都是在 ...
随机推荐
- mysql 删除表中记录
一.清除mysql表中数据 delete from 表名;truncate table 表名;不带where参数的delete语句可以删除mysql表中所有内容,使用truncate table也可以 ...
- Iterator、Iteratable与ListIterator
Iteratable: public interface Iterable<T> { Iterator<T> iterator(); default void forEach( ...
- CentOS 下安装和使用 Docker
引言: 在服务器开发过程中,环境部署无疑是及其繁琐的事情,特别是当项目数量和规模达到一定级别之后,在一台新的机器上部署项目环境无疑是极其漫长而痛苦的,那么什么办法能够实现我们的目标:在开发环境的一次配 ...
- ARM 平台下的 SSHD 配置
sshd_config 文件中 允许 root 用户登录 PermitRootLogin yes 配置为内部的 sftp Subsystem sftp internal-sftp key 配置 ssh ...
- Tomcat问题:Neither the JAVA_HOME nor the JRE_HOME environment variable is defined ,At least one of these environment variable is needed to run this program
一眼就能看出来是jdk的环境有问题,但是用了这么久的jdk一直都配置的好好的,怎么一到Tomcat上就这么矫情了. 最后查解决方案,原来是我的jdk从官网直接下载的,虽然我修改了java_home,但 ...
- HDU 1002:A + B Problem II(大数相加)
A + B Problem II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- Centos(linux)下的Python
Centos(linux)下安装python3(python2和python3共存) yum -y install lrzsz 首先安装lrzsz工具,lrzsz是一款在linux里可代替ftp上传和 ...
- java1.8操作日期
java1.8获取年份: int year = Calendar.getInstance().get(Calendar.YEAR); StringBuilder code = new StringBu ...
- 做Global Admin
globaladmin.4budget@nokia.com 10:22 https://ultima.int.net.nokia.com/eedb/Solutions/tools/ManageUser ...
- Python模块之virtualenvwrapper
Python的virtualenv工具可以创建隔离的Python环境, virtualenvwrapper是virtualenv的进一步封装工具,可以让它更好用. 安装 Linux 系统下: pip ...