上上篇博文【SSH进阶之路】Hibernate映射——一对一单向关联映射(五),我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息。

上篇博文【SSH进阶之路】Hibernate映射——一对一双向关联映射(六),双向关联映射解决了单向关联映射只能从一端加载信息的缺陷,当然,双向关联映射并不影响存储,只影响加载。下面我们开始今天的内容:

一对多关联映射

映射原理

一对多关联映射和多对一关联映射的映射原理是一致的,都是在多的一端加入一个外键,指向一的一端。关联关系都是由多端维护,只是在写映射时发生了变化。

多对一和一对多的区别

多对一和一对多的区别在于维护的关系不同:

(1)多对一:多端维护一端的关系,在加载多端时,可以将一端加载上来。

(2)一对多:一端维护多端的关系,在加载一端时,可以将多端加载上来。

分类

一对多单向关联映射

对象模型

从对象模型中,我们可以看出,Group持有User的一个引用。由于是单向关联,所以数据在加载Group时,会把User加载上来,但是User并不知道Group的存在。

我们先看一下Group和User的实体,以及映射文件。

Group

  1. package com.liang.hibernate;
  2. import java.util.Set;
  3. public class Group {
  4. private int id;
  5. private String name;
  6. private Set users;
  7. public int getId() {
  8. return id;
  9. }
  10. public void setId(int id) {
  11. this.id = id;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. public Set getUsers() {
  20. return users;
  21. }
  22. public void setUsers(Set users) {
  23. this.users = users;
  24. }
  25. }

User

  1. package com.liang.hibernate;
  2. public class User {
  3. private int id;
  4. private String name;
  5. public int getId() {
  6. return id;
  7. }
  8. public void setId(int id) {
  9. this.id = id;
  10. }
  11. public String getName() {
  12. return name;
  13. }
  14. public void setName(String name) {
  15. this.name = name;
  16. }
  17. }

User.hbm.xml

  1. <?xml version="1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping>
  6. <class name="com.liang.hibernate.User" table="t_user">
  7. <id name="id">
  8. <generator class="native"/>
  9. </id>
  10. <property name="name"/>
  11. </class>
  12. </hibernate-mapping>

Group.hbm.xml

  1. <?xml version="1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping>
  6. <class name="com.liang.hibernate.Group" table="t_group">
  7. <id name="id">
  8. <generator class="native"/>
  9. </id>
  10. <property name="name"/>
  11. <!-- users属性,表达的是本对象与User的一对多的关系 -->
  12. <set name="users">
  13. <!--当前表(Group)的主键-->
  14. <key column="groupid"/>
  15. <one-to-many class="com.liang.hibernate.User"/>
  16. </set>
  17. </class>
  18. </hibernate-mapping>

生成的表结构和测试数据

缺点

1)因为多端User不知道Group的存在(也就是User不维护与Group的关系),所以在保存User时,关系字段groupId为null,如果该字段设置为非空,则将无法保存数据。

2)因为User不维护关系,而Group维护关系,Group就会发出多余的update语句,保证Group和User有关系,这样加载Group时才把该Users对应的用户加载上来。

一对多双向关联映射

对象模型

双向关联映射对比单向关联映射,对象的加载方向由单向变成了双向。

我们看一下Group和User的实体,映射文件

Group

  1. package com.liang.hibernate;
  2. import java.util.Set;
  3. public class Group {
  4. private int id;
  5. private String name;
  6. private Set users;
  7. public int getId() {
  8. return id;
  9. }
  10. public void setId(int id) {
  11. this.id = id;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. public Set getUsers() {
  20. return users;
  21. }
  22. public void setUsers(Set users) {
  23. this.users = users;
  24. }
  25. }

User

  1. package com.liang.hibernate;
  2. public class User {
  3. private int id;
  4. private String name;
  5. private Group groups;
  6. public int getId() {
  7. return id;
  8. }
  9. public void setId(int id) {
  10. this.id = id;
  11. }
  12. public String getName() {
  13. return name;
  14. }
  15. public void setName(String name) {
  16. this.name = name;
  17. }
  18. public Group getGroups() {
  19. return groups;
  20. }
  21. public void setGroups(Group groups) {
  22. this.groups = groups;
  23. }
  24. }

Group.hbm.xml

  1. <?xml version="1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="com.liang.hibernate">
  6. <class name="Group" table="t_group">
  7. <id name="id">
  8. <generator class="native"/>
  9. </id>
  10. <property name="name"/>
  11. <!-- 影响控制反转:inverse="false",多的一端维护关系,让一的一端失效 -->
  12. <set name="users" inverse="true">
  13. <key column="groupid" not-null="true"/>
  14. <one-to-many class="User"/>
  15. </set>
  16. </class>
  17. </hibernate-mapping>

User.hbm.xml

  1. <?xml version="1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="com.liang.hibernate">
  6. <class name="User" table="t_user">
  7. <id name="id">
  8. <generator class="native"/>
  9. </id>
  10. <property name="name"/>
  11. <!-- groups属性,表达的是本对象与Group的多对一的关系 -->
  12. <many-to-one name="groups" class="Group" column="groupid"/>
  13. </class>
  14. </hibernate-mapping>

生成的表和测试数据

一对多双向关联的映射方式:
1)在一的一端的集合上采用<key>标签,在多的一端加入一个外键
2)在多的一端采用<many-to-one>标签

注意:<key>标签和<many-to-one>标签加入的字段保持一直,否则会产生数据混乱。

inverse属性:

inverse属性可以用在一对多和多对多双向关联上,inverse属性默认为false,为false表示本端维护关系,如果inverse为true,则本端不能维护关系,会交给另一端维护关系,本端失效。所以一对多关联映射我们通常在多的一端维护关系,让一的一端失效,所以设置为inverse为true。

注意:inverse属性,只影响数据的存储,也就是持久化。

目的

一对多双向关联映射的目的主要是为了解决一对多单向关联的缺陷而不是需求驱动的。

总结

一对多关联映射还是很简单的,下篇博文我们介绍多对多关联映射。谢谢关注。

最新文章

  1. MySQL多实例
  2. Java程序设计 实验三
  3. new 小记
  4. bash环境变量读取顺序
  5. MySQL中char(36)被认为是GUID导致的BUG及解决方案
  6. DataGuard相同SID物理Standby搭建
  7. 网站页面优化必然趋势—WebP 图片!
  8. PHP计划任务:如何使用Linux的Crontab执行PHP脚本
  9. opencv环境的搭建,并打开一个本地PC摄像头。
  10. [模拟Android微信]主界面
  11. asp.net mvc请求响应模型原理回顾
  12. Mac下node.js卸载方法收集
  13. MySQL之字符集-校对规则
  14. .Net程序调试与追踪的一些方法
  15. Mybatis源码解析-BoundSql
  16. markdown编辑器的学习
  17. linux 显示当前所在文件位置 以及git 分支所在
  18. Ping 笔记
  19. 滚动ListView时图像顺序混乱
  20. 【数论&amp;想法题】小C的问题 @&quot;科林明伦杯&quot;哈尔滨理工大学第八届程序设计竞赛

热门文章

  1. 基于qemu和unicorn的Fuzz技术分析
  2. IIS 使用 web.config 实现从 http 自动301跳转到 https 的方法
  3. 接口&amp;调用接口
  4. 学习:c++指向指针的指针(多级间接寻址)
  5. Web API design
  6. learning scala akka tell pattern(二)
  7. rpm 简单 package 创建demo
  8. 利用Python进行数据分析【第二版】【高清中文版英文版源代码】
  9. ICEM-带四分之一球体的矩形块
  10. php 把数字转化为大写中文—升级版