• Hibernate框架(三)框架中的关系映射


         在设计数据库时我们会考虑,表与表之间的关系,例如我们前边经常提到的一对一,一对多,多对多关系,在数据库中我们通过外键,第三张表等来实现这些关系。而Hibernate时间实体类和数据库中的表进行的映射,这些关系如何映射呢?这里简单总结一下:


              一,一对多,多对一关系映射,这里拿学生和班级进行简单演示:


                 1,学生的类和对应的映射文件的编写:


    1. private int sid ;  
    2. private String sname ;  
    3.   
    4. private Classes classes ; //,引入班级对象,多对一  

    1. <class name="com.ljh.hibernate.pojo.Student" table="t_student" lazy="false">  
    2.     <id name="sid" column="sid">  
    3.         <generator class="native"/>  
    4.     </id>  
    5.     <property name="sname" column="sname" type="java.lang.String" length="20" not-null="true"/>         
    6.       
    7.     <!--   
    8.         表示对象的关系:多对一  
    9.         name 表示当前类的关系对象  
    10.         column 表示数据库中外键字段(也是描述数据关系)  
    11.         class 表示name属性值的类型  
    12.         cascade 级联  
    13.             主动方所做的操作(insert,update,delete),被动方也跟着做相同的操作。  
    14.             取值:save-update、delete 、all  
    15.             save-update : 保存或更新当前对象时,级联保存或更新关联对象  
    16.             delete : 删除当前对象时,级联删除关联对象  
    17.             all : 包含save,update,delete三种操作。  
    18.             对于多对一的场合,级联不能使用delete和all,否则会违背数据关系完整性。  
    19.         lazy : 延迟加载   
    20.             延迟初始化对象信息,等使用对象时再查询数据库。   
    21.             false : 禁用延迟加载  
    22.             proxy : 使用延迟加载(默认值),采用cglib代理完成延迟加载的扩展功能。  
    23.             no-proxy :  不使用代理,完成延迟加载 。可以使用第三方字节码增强工具。  
    24.         fetch : 数据抓取策略  :根据主动方,查询被动方时所采用的查询方式。    
    25.             fetch="select" 默认值,会采用多条语句的方式查找,往往会延迟加载数据  
    26.             fetch="join"  默认会采用左连接查询数据,不会延迟加载数据。  
    27.                 not-null 如果取值为true,那么框架采用内连接查询数据。  
    28.      -->  
    29.     <many-to-one name="classes" column="cid" cascade="save-update" lazy="no-proxy" fetch="join" not-null="true" class="com.ljh.hibernate.pojo.Classes"></many-to-one>  
    30. </class>  


                 2,班级的实体类和对应的映射文件:


    1. private int cid ;  
    2. private String cname ;  
    3.   
    4. private Set<Student> studentSet = new HashSet<Student>(); //引入学生类的集合,一对多  

    1. <class name="com.ljh.hibernate.pojo.Classes" table="t_classes" >  
    2.     <id name="cid" column="cid">  
    3.         <generator class="native"/>  
    4.     </id>  
    5.     <property name="cname" column="cname" type="java.lang.String" length="20" not-null="true"/>     
    6.       
    7.     <!-- 声明   一对多映射  
    8.         lazy : 延迟加载  
    9.             false : 禁用延迟加载  
    10.             true : 延迟加载(默认值)  
    11.             extra : 支持延迟加载的。(推荐)  
    12.                 当获取集合自身信息时,可以发送高效的查询语句。  
    13.                 例如:只希望获取集合的长度,而不需要获取集合中数据的信息,框架会通过函数执行查询进行计算集合长度。。  
    14.       
    15.         fetch : 数据抓取策略  
    16.                 查询关联对象的数据时,所采用的查询方式。  
    17.             join : 通过一条连接语句进行立即查询。(延迟加载不起作用)  
    18.             select : 通过多条查询语句进行查询。  
    19.             subselect : 通过子查询语句进行立即查询。  (不推荐使用)(默认情况下和select取值结果相同)  
    20.           
    21.         not-null="true" 对于一对多的查询,即使设置了not-null语句,依然采用左连接查询。  
    22.           
    23.         Inverse="true",表示控制反转,由对方也就是学生方来进行管理外键。因为外键在学生    
    24.      -->  
    25.     <set name="studentSet" cascade="all" inverse="true" fetch="subselect">  
    26.         <key column="cid" not-null="true"></key>  
    27.         <one-to-many class="com.bjpowernode.hibernate.pojo.Student"/>  
    28.     </set>  
    29. </class>  

        二,自关联:就是在自己的类进行关联自己,例如父菜单与子菜单的关系,对应的实体类,和映射文件


    1. private int mid ;           private String name ;  
    2.           
    3.         private Set<Menu> menuSet = new HashSet<Menu>(); //父菜单与子菜单的关系为:一对多  
    4.           
    5.         private Menu pmenu ; //子菜单和父菜单的关系为:多对一  

    1. <class name="com.ljh.hibernate.pojo.Menu" table="t_menu" >  
    2.     <id name="mid" column="mid">  
    3.         <generator class="native"/>  
    4.     </id>  
    5.     <property name="name" column="name" type="java.lang.String" length="20" not-null="true"/>   
    6.       
    7.     <many-to-one name="pmenu" column="m_id" cascade="save-update"></many-to-one>  
    8.       
    9.     <!--  
    10.         自关联表的设计:外键字段不能为非空。 
    11.      -->  
    12.     <set name="menuSet" cascade="all" inverse="true">  
    13.         <key column="m_id"></key>  
    14.         <one-to-many class="com.ljh.hibernate.pojo.Menu"/>  
    15.     </set>  
    16. </class>  

               三,一对一关系映射:

                       1,假如是主键一对一用来映射:也就是说被动方的主键是来自于主动方的主键,也可以将之称之为外键:

                    类之间相互添加彼此的应用。

                    映射文件中主动方,增加一对一标签:

    1. <one-to-one name="userinfo" cascade="all" class="com.ljh.hibernate.pojo.UserInfo"></one-to-one>  
    2.   
    3.               被动方,主键又是外键,也添加一对一的映射标签:  
    4.     <id name="uid" column="uid">  
    5.         <generator class="foreign">  
    6.             <param name="property">user</param>  
    7.         </generator>  
    8.     </id>  
    9.       
    10.     <!--   
    11.         描述一对一关系关系映射  
    12.         constrained="true" : 表示强制要求一对一使用外键关联。增加外键约束。  
    13.      -->  
    14.     <one-to-one name="user" constrained="true"  class="com.ljh.hibernate.pojo.User"></one-to-one>  

                     2,使用外键约束,其实是多对一的特殊情况,例如学生对班级,

                         类添加彼此的应用。

                         映射文件中学生端主动端,添加外键进行约束,添加多对一标签,

    1. <!--   
    2.     unique : 唯一约束  
    3.       
    4.         如果外键含有unique约束,那么表示主动方和被动方的关系为一对一。  
    5.           
    6.         对于一对一映射来讲,可以设置级联关系为delete 和 all  
    7.           
    8.         根据主动方查询被动方关联数据,是支持延迟加载的。  
    9.  -->  
    10. <many-to-one name="classes" column="cid" unique="true" cascade="all" class="com.ljh.hibernate.pojo.Classes"></many-to-one>  
    11.   
    12.                班级端的映射文件:添加一对一的标签:  
    13. <one-to-one name="student" cascade="all" property-ref="classes" class="com.ljh.hibernate.pojo.Student"></one-to-one>  

               四,多对多的关系,例如学生对课程的对应,在数据库中会生成第三张表进行维护:

                       在各自的类中引入对方的set集合,表示多对多。

                       

    学生端:

    1. <set name="courseSet" table="t_student_course" cascade="save-update">  
    2.     <key column="sid"></key>  
    3.     <many-to-many class="com.ljh.hibernate.pojo.Course" column="cid"></many-to-many>  
    4.   
    5. ;/set>  

    课程端:

    1. <!--   
    2.     对于多对多来讲,级联只能设置cascade="save-update"是合理的  
    3.     inverse="true" 让集合一端去维护中间表数据。任意一端都可以。  
    4.  -->  
    5.   
    6. <set name="studentSet" table="t_student_course"  cascade="save-update"  inverse="true">  
    7.     <key column="cid"></key>  
    8.     <many-to-many class="com.ljh.hibernate.pojo.Student" column="sid"></many-to-many>  
    9. </set>  



                   五,联合主键的映射,这种情况很少见,看一下如何吧,

                   出现了这种联合键时,需要我们为其定义一个联合主键的类(实现Serializable接口),类中声明多个字段的属性,表示联合主键字段。

                   在配置映射文件时,主键的配置利用联合主键的标签即可:

    1. composite-id name="id">              <key-property name="title"></key-property>  
    2.                 <key-property name="author"></key-property>  
    3.             </composite-id>     

                 综上,为Hibernate中对数据库进行关联设置映射时的几个简单例子,主要是我们根据实际情况,掌握几个对应标签的使用,还有就是里边的属性的使用。像lazycascadefetch等等。注意观察其中的不同。这样进行了关联设置我们就可以很好的,根据类生成数据库,对数据库中的数据进行关联操作,更加合理化!
  • 相关阅读:
    用Processon在线绘制UML的尝试
    软工UML学习札记
    结对项目:计算器 第三篇
    结对项目:计算器 第二篇
    TXT四则运算计算器 后日谈
    TXT四则运算计算器
    软件工程作业 四则运算(一)
    敏捷开发
    如何做“足够好”的软件
    关于如何衡量个人在各自团队的效率和绩效
  • 原文地址:https://www.cnblogs.com/love-omnus/p/4196613.html
Copyright © 2020-2023  润新知