`

Hibernate4实战 之 第四部分:关系映射

 
阅读更多

数据表之间的关系分为三类:一对一、一对多、多对多
一对一数据表(部门表  和  部门主管表)
一对多数据表(部门表  和  部门下的人员表)
多对多数据表(部门表  和  人员表)
 
根据相互寻找的关系又分:单向和双向
对象一对一 (双向

java代码:
  1. public class A {  
  2. private B b = null;  }  
  3. public class B {  
  4. private A a = null;  }  
  5. n对象一对多 (双向)  
  6. public class A {  
  7. private B b = null;  }  
  8. public class B {  
  9. private Collection<A> colA = null;  }  
  10. n对象多对多 (双向)  
  11. public class A {  
  12. private Collection<B> colB = null;  }  
  13. public class B {  
  14. private Collection<A> colA = null;  }  
 
双向一对多是最常用的映射关系
<key>元素
<key> 元素在父映射元素定义了对新表的连接,并且在被连接表中定义了一个外键引用原表的主键的情况下经常使用。

java代码:
  1. <key  
  2. column="columnname"(1)  
  3. on-delete="noaction|cascade"(2)  
  4. property-ref="propertyName"(3)  
  5. not-null="true|false"(4)  
  6. update="true|false"(5)  
  7. unique="true|false"(6)  
  8. />  
(1)column(可选):外键字段的名称。也可以通过嵌套的 <column> 指定。
(2)on-delete(可选,默认是 noaction):表明外键关联是否打开数据库级别的级联删除。
(3)property-ref(可选):表明外键引用的字段不是原表的主键(提供给遗留数据)。
(4)not-null(可选):表明外键的字段不可为空,意味着无论何时外键都是主键的一部分。
(5)update(可选):表明外键决不应该被更新,这意味着无论何时外键都是主键的一部分。
(6)unique(可选):表明外键应有唯一性约束,这意味着无论何时外键都是主键的一部分。
对那些看重删除性能的系统,推荐所有的键都应该定义为 on-delete="cascade",这样Hibernate 将使用数据库级的 ON CASCADE DELETE 约束,而不是多个 DELETE 语句用于映射集合类的
Hibernate映射元素取决于接口的类型。比如,<set>元素用来映射Set类型的属性:

java代码:
  1. <class name="Product">  
  2. <id name="serialNumber" column="productSerialNumber"/>  
  3. <set name="parts">  
  4. <key column="productSerialNumber" not-null="true"/>  
  5. <one-to-many class="Part"/>  
  6. </set>  
  7. </class>  
除了<set>,还有<list>, <map>, <bag>, <array> 和 <primitive-array> 映射元素。<map>具有代表性 ,如下:

java代码:
  1. <map  
  2. name="propertyName" (1)  
  3. table="table_name" (2)  
  4. schema="schema_name" (3)  
  5. lazy="true|extra|false" (4)  
  6. inverse="true|false" (5)  
  7. cascade=“all|none|save-update|delete|all-delete-orphan|delete-orphan”(6) sort="unsorted|natural|comparatorClass" (7)  
  8. order-by="column_name asc|desc" (8)  
  9. where="arbitrary sql where condition" (9)  
  10. fetch="join|select|subselect" (10)  
  11. batch-size="N" (11)  
  12. access="field|property|ClassName" (12)  
  13. optimistic-lock="true|false" (13)  
  14. mutable="true|false" (14)  
  15. >  
  16. <key .... /> <map-key .... />  
  17. <element .... />  
  18. </map>  
(1) name 集合属性的名称
(2) table (可选——默认为属性的名称)这个集合表的名称(不能在一对多的关联关系中使用)
(3) schema (可选) 表的schema的名称, 他将覆盖在根元素中定义的schema
(4) lazy (可选--默认为true) 可以用来关闭延迟加载(false),
(5) inverse (可选——默认为false) 标记这个集合作为双向关联关系中的方向一端。
(6) cascade (可选——默认为none) 让操作级联到子实体
(7) sort(可选)指定集合的排序顺序
(8) order-by (可选, 仅用于jdk1.4) 指定表的字段(一个或几个)再加上asc或者desc(可选), 定义Map,Set和Bag的迭代顺序
(9) where (可选) 指定任意的SQL where条件, 该条件将在重新载入或者删除这个集合时使用(当集合中的数据仅仅是所有可用数据的一个子集时这个条件非常有用)
(10) fetch (可选, 默认为select) 用于在外连接抓取、通过后续select抓取和通过后续subselect抓取之间选择。
(11) batch-size (可选, 默认为1) 指定通过延迟加载取得集合实例的批处理块大小
(12) access(可选-默认为属性property):Hibernate取得集合属性值时使用的策略
(13) 乐观锁 (可选 - 默认为 true): 对集合的状态的改变会是否导致其所属的实体的版本增长。 (对一对多关联来说,关闭这个属性常常是有理的)
(14) mutable(可变) (可选 - 默认为true): 若值为false,表明集合中的元素不会改变(在某些情况下可以进行一些小的性能优化)。
集合外键
集合实例在数据库中依靠持有集合的实体的外键加以辨别。此外键作为集合关键字段加以引用。集合关键字段通过 <key> 元素映射。
在外键字段上可能具有非空约束。对于大多数集合来说,这是隐含的。对单向一对多关联来说,外键字段默认是可以为空的,因此你可能需要指明 not-null=“true”。示例如下:

java代码:
  1. <key column="productSerialNumber" not-null="true"/>  
外键约束可以使用 ON DELETE CASCADE,示例如下:

java代码:
  1. <key column="productSerialNumber" on-delete="cascade"/>  
  2. one-to-one  
通过 one-to-one 元素,可以定义持久化类的一对一关联。

java代码:
  1. <one-to-one  
  2. name="propertyName"(1)  
  3. class="ClassName"(2)  
  4. cascade="cascade_style"(3)  
  5. constrained="true|false"(4)  
  6. fetch="join|select"(5)  
  7. property-ref="propertyNameFromAssociatedClass"(6)  
  8. access="field|property|ClassName"(7)  
  9. formula="any SQL expression"(8)  
  10. lazy="proxy|no-proxy|false"(9)  
  11. entity-name="EntityName"(10)  
  12. />  
(1)name:属性名。
(2)class(可选 — 默认是通过反射得到的属性类型):被关联的类的名字。
(3)cascade(级联)(可选)表明操作是否从父对象级联到被关联的对象。
(4)constrained(约束)(可选)表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。这个选项影响 save() 和 delete() 在级联执行时的先后顺序以及决定该关联能否被委托(也在 schema export tool 中被使用)。
(5)fetch(可选 — 默认为 select):在外连接抓取(outer-join fetching)和序列选择抓取(sequential select fetching)两者中选择其一。
(6)property-ref:(可选)指定关联类的属性名,这个属性将会和本类的主键相对应。如果没有指定,会使用对方关联类的主键。
(7)access(可选 — 默认为 property):Hibernate 用来访问属性值的策略。
(8)formula (可选):绝大多数一对一的关联都指向其实体的主键。在一些少见的情况中,你可能会指向其他的一个或多个字段,或者是一个表达式,这些情况下,你可以用一个 SQL 公式来表示。(可以在 org.hibernate.test.onetooneformula 找到例子)
(9)lazy(可选 — 默认为 proxy):默认情况下,单点关联是经过代理的。lazy="no-proxy"指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche lazily)(需要运行时字节码的增强)。 lazy="false"指定此关联总是被预先抓取。注意,如果constrained="false", 不可能使用代理,Hibernate会采取预先抓取。
(10)entity-name(可选):被关联的类的实体名。
nmany-to-one
通过 many-to-one 元素,可以定义一种常见的与另一个持久化类的多对一关联,这个表的一个外键引用目标表的主键字段。

java代码:
  1. <many-to-one  
  2. name="propertyName" (1)  
  3. column="column_name" (2)   
  4. class="ClassName" (3)  
  5. cascade="cascade_style"(4)  
  6. fetch="join|select" (5)  
  7. update="true|false" (6)  
  8. insert="true|false" (7)  
  9. property-ref="propertyNameFromAssociatedClass"(8)  
  10. access="field|property|ClassName"(9)  
  11. unique="true|false" (10)  
  12. not-null="true|false" (11)  
  13. optimistic-lock="true|false“ (12)  
  14. lazy="proxy|no-proxy|false" (13)  
  15. not-found="ignore|exception“ (14)  
  16. entity-name="EntityName" (15)  
  17. formula="arbitrary SQL expression"(16)  
  18. />  
  19.    
(1)name:属性名。
(2)column(可选):外键字段的名称。也可以通过嵌套的 <column> 指定。
(3)class(可选 — 默认是通过反射得到的属性类型):被关联的类的名字。
(4)cascade(级联)(可选)表明操作是否从父对象级联到被关联的对象。
(5)fetch(可选 — 默认为 select):在外连接抓取和序列选择抓取两者中选择其一。
(6)update, insert(可选 — 默认为 true)指定对应的字段是否包含在用于 UPDATE 和/或 INSERT的 SQL 语句中。如果二者都是false,则这是一个纯粹的 “外源性(derived)”关联,它的值是通过
 映射到同一个(或多个)字段的某些其他属性得到 或者通过 trigger(触发器)、或其他程序生成。
(7)property-ref:(可选)被关联到此外键的类中的对应属性的名字。如果不指定,使用被关联类的主键
(8)access(可选 — 默认为 property):Hibernate 用来访问属性值的策略。
(9)unique(可选):使用 DDL 为外键字段生成一个唯一约束。此外, 这也可以用作 propertyref的目标属性。这使关联同时具有一对一的效果。
(10)not-null(可选):使用 DDL 为外键字段生成一个非空约束。
(11)optimistic-lock(可选 — 默认为 true):指定这个属性在做更新时是否需要获得乐观锁定。换句话说,它决定这个属性发生脏数据时版本(version)的值是否增长。
(12)lazy(可选 — 默认为 proxy):默认情况下,单点关联是经过代理的。lazy="no-proxy" 指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche lazily)(需要运行时字节码的增强)。lazy="false" 指定此关联总是被预先抓取。
(13)not-found(可选 - 默认为exception):指定如何处理引用缺失行的外键:ignore 会把缺失的行作为一个空关联处理。
(14)entity-name(可选):被关联的类的实体名。
(15)formula(可选):SQL 表达式,用于定义 computed(计算出的)外键值。
 
one-to-many
通过 one-to-many 元素,可以定义一种常见的与另一个持久化类的一对多关联。

java代码:
  1. <one-to-many  
  2. class="ClassName"(1)  
  3. not-found="ignore|exception"(2)  
  4. entity-name="EntityName"(3)  
  5. />  
(1)class(必需):被关联类的名称。
 
(2)not-found(可选 - 默认为exception):指明若缓存的标示值关联的行缺失,该如何处理:ignore 会把缺失的行作为一个空关联处理。
 
(3)entity-name(可选):被关联的类的实体名,作为 class 的替代。
 
注意:<one-to-many> 元素不需要定义任何字段。也不需要指定表名。
还是用示例来看,下面作一个双向一对多的关系示例:
1:新建一个Parent对象和Child对象,Parent对象里面有一个Child对象的集合,Child对象里面有一个对Parent对象的引用,如下:

java代码:
  1. public class Parent{  
  2.   private String id;  
  3.   private String name;  
  4.   private Set children = new HashSet();  
  5. ……  
  6. }  
  7. public class Child {  
  8.   private String uuid;  
  9.   private String address;  
  10.   private String postCode;  
  11.   private Parent parent;  
  12. ……  
  13. }  
  14. Parent.hbm.xml:  
  15. <?xml version="1.0" encoding="UTF-8"?>  
  16. <!DOCTYPE hibernate-mapping PUBLIC  
  17.     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  18.     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  19. <hibernate-mapping>  
  20.     <class name="cn.javass.h3.parentchild.Parent" table="tbl_parent" dynamic-update="true" dynamic-insert="true" lazy="true">  
  21.         <id name="id" column="uuid" type="java.lang.String" unsaved-value="any">  
  22.             <generator class="assigned"> </generator>  
  23.         </id>  
  24.         <property name="name"  update="true" insert="true"/>         
  25. <set name="children" inverse="true"  cascade="all">  
  26. <key column="tbl_parent_fk"/>  
  27. <one-to-many class="cn.javass.h3.parentchild.Child"/>  
  28. </set>  
  29.     </class>  
  30. </hibernate-mapping>  
  31.    
  32. Child.hbm.xml:  
  33. <?xml version="1.0" encoding="UTF-8"?>  
  34. <!DOCTYPE hibernate-mapping PUBLIC  
  35.     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  36.     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  37. <hibernate-mapping>  
  38.     <class name="cn.javass.h3.parentchild.Child" table="tbl_child" dynamic-update="true" dynamic-insert="true" lazy="true">  
  39.         <id name="uuid" column="uuid" type="java.lang.String" unsaved-value="any">  
  40.             <generator class="assigned"> </generator>  
  41.         </id>  
  42.         <property name="address"  update="true" insert="true"/>  
  43. <property name="postCode"  update="true" insert="true"/>  
  44. <many-to-one  
  45. name="parent"  
  46. column="tbl_Parent_fk"  
  47. class="cn.javass.h3.parentchild.Parent"  
  48. not-null="true"  
  49. />  
  50.     </class>  
  51. </hibernate-mapping>  
客户端测试TestMR.java文件太长,直接看演示好了。
在这个测试里面分别演示了单独的操作和级联的操作。
inverse:指定由哪一方来维护双方的关联关系,默认是false,也就是双方都维护,主要用在一对多 和 多对多中。
在一对多中使用inverse的时候,通常是在”一”这一端设置inverse=true,他的意思就是由多的那一端去维护关系,非反向端用于把内存中的表示保存到数据库中。如下:
Parent p = new Parent();
Child c = new Child();
c.setParent(p); //维护父子之间关系
p.getChildren().add(c);
ninverse还有一个重要特点就是会优化Sql
ncascade:定义对象的级联关系
all : 所有情况下均进行关联操作
none:所有情况下均不进行关联操作。这是默认值
save-update:在执行save/update/saveOrUpdate时进行关联操作
delete:在执行delete时进行关联操作
简单的示范一下双向的一对一
双向一对一的操作是类似于双向一对多的,只是配置上有一些不同:
1:Parent里面的配置,示例如下:
<one-to-one name= “cc” class= “cn.javass.h3.parentchild.Child” cascade= “all”  property-ref= “parent“/>这里的property-ref参照的是Child对象里面的属性。
2:Child里面的配置,不是使用one-to-one,而是仍使用many-to-one,示例如下:
<many-to-one name=“parent” class=“cn.javass.h3.parentchild.Parent” column=“tbl_parent_fk”/>
3:测试程序里面,原来调用集合的地方,变成调用一个Child对象,其他就差不多了,可以测试看看。
 
Hibernate4的过滤器
Hibernate3 新增了对某个类或者集合使用预先定义的过滤器条件(filter criteria)的功能。过滤器条件相当于定义一个 非常类似于类和各种集合上的“where”属性的约束子句, 但是过滤器条件可以带参数,应用程序可以在运行时决 定是否启用给定的过滤器,以及使用什么样的参数值。过滤器的用法很像数据库视图,只不过是在应用程序中确定使用什么样的参数的。
 
定义过滤器
要使用过滤器,首先要在相应的映射节点中定义。而定义一个过滤器,要用到位于 <hibernatemapping/>节点之内的 <filter-def/> 节点:
示例如下:

java代码:
  1. <filter-def name="myFilter">  
  2. <filter-param name="myFilterParam" type="string"/>  
  3. </filter-def>  
 
使用过滤器之配置
定义好之后,就可以在某个类中使用这个过滤器:

java代码:
  1. <class name="myClass" ...>  
  2. ...  
  3. <filter name="myFilter" condition=":myFilterParam=FILTERED_COLUMN"/>  
  4. </class>  
或者也可以在某个集合使用它:

java代码:
  1. <set ...>  
  2. <filter name="myFilter" condition=":myFilterParam=FILTERED_COLUMN"/>  
  3. </set>  
 
在同时可以使用多个过滤器。
使用过滤器之程序
在程序中,需要使用session接口中的:enableFilter(String filterName),getEnabledFilter(String filterName),和 disableFilter(String filterName)方法。Session中默认不启用过滤器,必须通过enabledFilter() 方法显式的启用。
示例代码session.enableFilter("myFilter").setParameter("myFilterParam", "some-value");
过滤器示例
在Parent.hbm.xml中定义有如下的过滤器:

java代码:
  1. <filter-def name="myFilter">  
  2. <filter-param name="myFilterParam" type="string"/>  
  3. </filter-def>  
  4. <filter-def name="myFilter2">  
  5. <filter-param name="myFilterParam" type="int"/>  
  6. <filter-param name="myFilterParam2" type="int"/>  
  7. </filter-def>  
在定义Child集合中使用

java代码:
  1. <set name="children" inverse="true" cascade="all" fetch="select" lazy="false" batch-size="3">  
  2. <key column="tbl_parent_fk"/>  
  3. <one-to-many class="cn.javass.h3.parentchild.Child" />  
  4. <filter name="myFilter"  
  5. condition="address like :myFilterParam"></filter>  
  6. <filter name="myFilter2" condition="uuid &gt;= :myFilterParam and uuid &lt;= :myFilterParam2"></filter>  
  7. </set>  
程序中使用示例

java代码:
  1. s.enableFilter("myFilter").setParameter("myFilterParam""%1%");  
  2. s.enableFilter("myFilter2").setParameter("myFilterParam"1)  
  3. .setParameter("myFilterParam2"3);  
  4. Query q = s.createQuery("select p from Parent as p  ");  
  5. System.out.println("p==="+p.getChildren());  
  6.    
视频配套PPT,视频地址【 Hibernate4实战-独家视频课程 
原创内容 转自请注明【 http://sishuok.com/forum/blogPost/list/2479.html#7154
4
8
分享到:
评论

相关推荐

    Hibernate4实战 之第七部分

    ### Hibernate4实战之第七部分:最佳实践 #### 设计细颗粒度的持久类并使用`&lt;component&gt;`实现映射 在Hibernate中,细颗粒度的持久类是指将实体中的复杂属性拆分成单独的对象进行管理。例如,对于一个用户实体中的...

    hibernate实战 英文版

    2. **对象关系映射(ORM)**:ORM是Hibernate的核心功能之一,书中对此进行了详尽的阐述,包括如何将Java对象映射到数据库表中的记录。 3. **持久化管理**:持久化是ORM中的一个重要概念,本书探讨了如何有效地管理...

    Hibernate4实战(pdf_source).

    《Hibernate4实战》这本书主要涵盖了Hibernate4框架在Java开发中的应用和高级技术,包括关系映射、事务管理、核心原理、性能优化以及二级缓存的使用。以下是对这些主题的详细解析: 1. **关系映射**:Hibernate是...

    Hibernate实战第二版

    《图灵程序设计丛书·Hibernate实战(第2版)》是毋庸置疑的Hibernate和ORM(对象/关系映射)权威著作,由包括Hibernate之父在内的两位核心开发人员亲自执笔,详细讲述了Hibernate 3.2、Java Persistence和EJB 3.0标准...

    Hibernate4实战

    在第二部分中,《Hibernate4实战》详细讲解了Hibernate的配置过程。这包括`hibernate.cfg.xml`配置文件的解析,如何设置数据库连接信息(如驱动、URL、用户名和密码),以及如何定义日志级别和其他高级配置选项。...

    Hibernate实战(第2版).pdf

    《Hibernate实战(第2版)》是一本深入探讨Java持久化框架Hibernate的专业书籍,它针对的是Java开发人员,特别是那些希望提升数据库管理效率和优化应用程序性能的开发者。Hibernate作为一个开源的对象关系映射(ORM...

    Hibernate实战(第2版) 高清扫描版

    《Hibernate实战(第2版)》是一本深入探讨Java持久化框架Hibernate的专业书籍,高清扫描版使得读者可以清晰地获取书中的每一个细节。Hibernate作为Java领域最流行的ORM(对象关系映射)框架之一,它极大地简化了...

    hibernate实战第二版.pdf

    《Hibernate实战》第二版是一本深入探讨Java领域中ORM(对象关系映射)技术的经典教程。Hibernate作为Java EE开发中的重要框架,它有效地解决了数据库与Java对象之间的转换问题,简化了数据操作。这本书针对初学者和...

    hibernate实战 第2版.pdf

    但是,考虑到标题和描述中提到的“hibernate实战 第2版.pdf”,我们可以基于这个信息来生成关于Hibernate的知识点。以下是根据这一主题撰写的详细知识点: Hibernate是一个开放源代码的对象关系映射(ORM)框架,...

    Hibernate实战第2版.zip

    《Hibernate实战第2版》是IT领域中关于Java持久化框架Hibernate的一本深入实践的书籍。Hibernate是一个开源的ORM(对象关系映射)框架,它为Java开发者提供了在关系数据库和面向对象编程之间架起桥梁的工具。这本书...

    Hibernate实战(第2版 中文高清版)

     第4章 映射持久化类   4.1 理解实体和值类型   4.1.1 细粒度的领域模型   4.1.2 定义概念   4.1.3 识别实体和值类型   4.2 映射带有同一性的实体   4.2.1 理解Java同一性和等同性   4.2.2 处理...

    轻量级Java EE企业应用实战(第4版) Struts 2+Spring 4+Hibernate整合开发 光盘 源码

    《轻量级Java EE企业应用实战(第4版)》这本书深入探讨了Struts 2、Spring 4和Hibernate这三大框架的整合开发,旨在帮助读者掌握如何在实际项目中高效构建Java EE应用。SSH(Struts 2、Spring、Hibernate)是Java ...

    MLDN_Hibernate开发实战讲解视频教程

    【标题】"MLDN_Hibernate开发实战讲解视频教程"涵盖了关于Hibernate框架的深入学习和实践应用,这是一款广泛用于Java企业级应用中的对象关系映射(ORM)工具。Hibernate简化了数据库操作,允许开发者用面向对象的...

    hibernate开发与实战 源代码

    1. **Chapter 01 - 第一次接触Hibernate**: 这部分通常会介绍如何搭建Hibernate环境,包括配置Hibernate的核心配置文件(hibernate.cfg.xml)、实体类的创建以及持久化操作的基本语法。 2. **Chapter 06 - 排序(Order...

    轻量级J2EE企业应用实战——Struts+Spring+Hibernate整合开发 源码第五部分

    在本资源中,我们关注的是"轻量级J2EE企业应用实战——Struts+Spring+Hibernate整合开发"的源码第五部分。这个主题涉及到Java企业级应用开发中的三个核心框架:Struts、Spring和Hibernate的集成使用。下面将详细阐述...

    Hibernate实战(第2版)

    ### Hibernate实战(第2版)知识点详解 #### 一、Hibernate框架概述 1. **定义与特点**: - **Hibernate**是一种Java环境下基于JDBC API的ORM(Object Relational Mapping)框架,它提供了从Java类到数据库表以及从...

    精通hibernate3.0(第三版).rar

    本书全面覆盖了Hibernate 3.0的核心概念、API以及最佳实践,旨在帮助读者掌握这一强大的ORM(对象关系映射)框架,提升开发效率。 首先,Hibernate作为一个开源的Java库,它为开发者提供了在Java应用程序中操作...

Global site tag (gtag.js) - Google Analytics