Hibernate一对多双向关联

如果只是最简单的关联起来,没有级联,没有inverse

<set name="users" table="USER">
<!-- 这个需要填写别的表的外键,而不是本表的主键 -->
<key column="DEPART_ID" />
<one-to-many class="model.User" />
</set>

<many-to-one name="department" column="DEPART_ID" />

那么在保存对象的时候必须进行两步操作

第一步先保存主表数据,即被引用外键的表的数据

第二步再保存从表数据,即引用主表外键的表的数据

如果直接保存从表数据,由于没有设置级联和inverse,Hibernate肯定不知道先给你把主表数据保存起来。

下面看看查询主表对象会出现什么效果。

查询主表对象的时候会直接将所有的从表对象加载出来,貌似没有使用懒加载,下面加个懒加载属性试试。lazy="true"属性加到set标签上即可。

删除主表对象的时候如果没有加上级联cascade删除的话,那么不会删除从表的对象,会将从表对象的外键属性设置为空,这样看来的话如果不设置级联,那么也不能设置外键not-null,否则会报错,如果设置了从表外键非空,有两种方法去删除,一种是先根据主表的主键找到所有从表数据并删除,然后再删除主表数据,一种是设置级联,那么在删除主表数据的时候,Hibernate会自动帮你先删除从表的数据,设不设置级联应该根据业务需要来定,我觉得最好不要设置,而是自己来做删除这个操作,并且外键也不要限制必须非空。如果一开始外键没有设置非空限制,后来加上的话,hibernate不会根据<property name="hbm2ddl.auto">update</property>更新数据库表结构,必须将update改为create。

如果在从表的many-to-one标签上加入cascade="save-update"属性,那么在保存从表对象的时候会自动保存主表对象。但是有个问题就是如果从表数据比较多,因为从表是一对多中多得一方,那么保存起来代码会很多,解决方法就是将cascade="save-update"属性放到主表映射文件的set标签上面。如此做得话保存代码只需像如下:

//创建需要持久化的对象
User u1 = new User();
u1.setName("user1");
User u2 = new User();
u2.setName("user2");
Department d1 = new Department();
d1.setName("depart1");
d1.getUsers().add(u1);
d1.getUsers().add(u2);
//数据库保存数据操作代码
session.save(d1);
但是这样有个弊端就是保存主表对象时的sql语句会增加多条update语句,如果数据多得话可能会影响性能的。。解决方法就是在set标签上加一个inverse="true"属性,如果这样做得话,就可以解决上面的问题了,但是代码需要像下面的这样。

//创建需要持久化的对象
User u1 = new User();
u1.setName("user1");
User u2 = new User();
u2.setName("user2");
Department d1 = new Department();
d1.setName("depart1");
d1.getUsers().add(u1);
d1.getUsers().add(u2);
u1.setDepartment(d1);
u2.setDepartment(d1);
session.save(d1);


因为在保存主表对象的时候检查映射文件的时候,由于设置了set级联保存和更新,那么会去检查主表对象的集合属性,但是由于设置了inverse="true"的属性,那么控制权其实是交给了集合中的对象,集合对象会去先保存跟自己关联的主表对象,再保存自己,如此就不会多出几条update语句。


但是又有个问题,比如d1中加了两个用户u1和u2,但是u1不设置Department属性,那么最后存到数据库的数据中u1的部门属性就是空的了,如果把u1设置成另外一个新部门,那么保存的时候会报错,因为另外一个新部门没有持久化,如果再把User的cascade属性设为"save-update",那么最后u1就是新部门的,这样的话关联关系就会混乱了,所以最好还是不要这样做。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
疫情居家办公系统管理系统按照操作主体分为管理员和用户。管理员的功能包括办公设备管理、部门信息管理、字典管理、公告信息管理、请假信息管理、签到信息管理、留言管理、外出报备管理、薪资管理、用户管理、公司资料管理、管理员管理。用户的功能等。该系统采用了MySQL数据库,Java语言,Spring Boot框架等技术进行编程实现。 疫情居家办公系统管理系统可以提高疫情居家办公系统信息管理问题的解决效率,优化疫情居家办公系统信息处理流程,保证疫情居家办公系统信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理疫情居家办公系统信息,包括外出报备管理,培训管理,签到管理,薪资管理等,可以管理公告。 外出报备管理界面,管理员在外出报备管理界面中可以对界面中显示,可以对外出报备信息的外出报备状态进行查看,可以添加新的外出报备信息等。签到管理界面,管理员在签到管理界面中查看签到种信息,签到描述信息,新增签到信息等。公告管理界面,管理员在公告管理界面中新增公告,可以删除公告。公告型管理界面,管理员在公告型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值