论坛首页 入门讨论版 Hibernate

对象/关系映射—Hibernate(第二章)

浏览 696 次
该帖已经被评为新手帖
作者 正文
最后更新时间:2008-04-12
 
映射声明(Mapping declaration)
  1. 对象和关系数据库之间的映射是用一个XML文档(XML document)来定义的。这个映射文档被设计为易读的,并且可以手工修改。映射语言是以Java为中心的,意味着映射是按照持久化类的定义来创建的,而非表的定义。   
  2.     
  3. 请注意,虽然很多Hibernate用户选择手工定义XML映射文档,也有一些工具来生成映射文档,包括XDoclet,Middlegen和AndroMDA.   
java 代码
  1. hibernate-mapping   
  2.     一、类层次。class  
  3.         1、主键。id   
  4.         2、基本类型。property   
  5.         3、自定义类。many-to-one  |  one-to-one   
  6.         4、集合。set | list | map | array   
  7.             4.1、one-to-many   
  8.             4.2、many-to-many   
  9.         5、子类。subclass | joined-subclass   
  10.         6、其它。component | any等   
  11.     二、查询语句。Query   
  12. 说明:一个Hibernate-mapping中可以同时定义多个类。Query非常简单,主要是用来放置查询语句,便于对数据库查询的统一管理和优化。   
  13. "1.0"?>    
  14. "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">    
  15. package="eg">    
  16.     <class name="Cat" table="CATS" discriminator-value="C">   
  17.          "id" column="uid" type="long"class="hilo"/>     "subclass" type="character"/>    
  18.         "birthdate" type="date"/>    
  19.         "color" not-null="true"/>   
  20.          "sex" not-null="true" update="false"/>    
  21.         "weight"/>   
  22.          "mate" column="mate_id"/>   
  23.          "kittens""mother_id"/>   
  24.             class="Cat"/>   
  25.             
  26.          "DomesticCat" discriminator-value="D">    
  27.         "name" type="string"/>    
  28.      class>    
  29.     <class name="Dog">   
  30.             
  31.     class>    
  32.     
  33.   
 
Doctype
  1. 所有的XML映射都需要定义如上所示的doctype。DTD可以从上述URL中获取,或者在hibernate-x.x.x/src/net/sf/hibernate目录中,或hibernate.jar文件中找到。Hibernate总是会在它的classptah中首先搜索DTD文件。   

 

 
hibernate-mapping
  1. 这个元素包括三个可选的属性。schema属性,指明了这个映射所引用的表所在的schema名称。假若指定了这个属性,表名会加上所指定的schema的名字扩展为全限定名。假若没有指定,表名就不会使用全限定名。default-cascade指定了未明确注明cascade属性的Java属性和集合类Java会采取什么样的默认级联风格。auto-import属性默认让我们在查询语言中可以使用非全限定名的类名。    
  2.   
  3.   
  4. <hibernate-mapping schema="schemaName" (1)    
  5.     default-cascade="none|save-update" (2)    
  6.     auto-import="true|false"               (3)   
  7.      package="package.name"            (4)   
  8.  />    

 

 
hibernate-mapping
  1. (1)schema (可选): 数据库schema名称   
  2. (2)default-cascade (可选 - 默认为 none): 默认的级联风格   
  3. (3)auto-import (可选 - 默认为 true): 指定是否我们可以在查询语言中使用非全限定的类名(仅限于本映射文件中的类)。    
  4. (4)package (可选): 指定一个包前缀,如果在映射文档中没有指定全限定名,就使用这个包名。    
  5.   
  6. 假若你有两个持久化类,它们的非全限定名是一样的(就是在不同的包里面--译者注),你应该设置auto-import="false"。假若说你把一个“import过”的名字同时对应两个类, Hibernate会抛出一个异常。   

 

 
类层次class
  1. 你可以使用class元素来定义一个持久化类:   
  2. <class name="ClassName" (1)  table="tableName" (2)   
  3.  discriminator-value="discriminator_value" (3)    
  4. mutable="true|false" (4)   schema="owner" (5)   
  5.  proxy="ProxyInterface" (6)  dynamic-update="true|false" (7)   
  6.  dynamic-insert="true|false" (8)  select-before-update="true|false" (9)   
  7.  polymorphism="implicit|explicit" (10)   
  8.  where="arbitrary sql where condition" (11)   
  9.  persister="PersisterClass" (12)  batch-size="N" (13)    
  10. optimistic-lock="none|version|dirty|all" (14)    
  11.  lazy="true|false" (15) />    
  12.   
  13.   
  14. (1)name: 持久化类(或者接口)的Java全限定名。   
  15. (2)table: 对应的数据库表名。    
  16. (3)discriminator-value(辨别值) (可选 - 默认和类名一样):一个用于区分不同的子类的值,在多态行为时使用。   
  17. (4)mutable(可变) (可选, 默认值为 true): 表明该类的实例可变(不可变)。    
  18. (5)schema (可选): 覆盖在根<hibernate-mapping>元素中指定的schema名字。    
  19. (6)proxy (可选): 指定一个接口,在延迟装载时作为代理使用。你可以在这里使用该类自己的名字。    
  20. (7)dynamic-update(动态更新) (可选,默认为false): 指定用于UPDATE 的SQL将会在运行时动态生成,并且只更新那些改变过的字段。    
  21. (8)dynamic-insert(动态插入) (可选, 默认为false): 指定用于INSERT的 SQL 将会在运行时动态生成,并且只包含那些非空值字段。    
  22. (9)select-before-update (可选,默认值为false): 指定Hibernate除非确定对象的确被修改了,不会执行SQL UPDATE操作。在特定场合(实际上,只会发生在一个临时对象关联到一个新的session中去,执行update()的时候),这说明Hibernate会在UPDATE之前执行一次额外的SQL SELECT操作,来决定是否应该进行UPDATE。    
  23. (10)polymorphism(多形,多态) (可选, 默认值为 implicit (隐式)): 界定是隐式还是显式的使用查询多态。    
  24. (11)where (可选) 指定一个附加的SQLWHERE 条件,在抓取这个类的对象时会一直增加这个条件。    
  25. (12)persister (可选): 指定一个定制的ClassPersister。    
  26. (13)batch-size (可选,默认是1) 指定一个用于根据标识符抓取实例时使用的“batch size”(批次抓取数量)。    
  27. (14)optimistic-lock(乐观锁定) (可选,默认是version): 决定乐观锁定的策略。    
  28. (15)lazy(延迟) (可选): 假若设置 lazy="true",就是设置这个类自己的名字作为proxy接口的一种等价快捷形式。  

 

 
主键-id
  1. 被映射的类必须声明对应数据库表主键字段。大多数类有一个JavaBeans风格的属性,为每一个实例包含唯一的标识。<id> 元素定义了该属性到数据库表主键字段的映射。    
  2.   
  3. <id name="propertyName" (1)    
  4. type="typename" (2)    
  5. column="column_name" (3)    
  6. unsaved-value="any|none|null|id_value" (4) access="field|property|ClassName"> (5)   
  7.  <generator class="generatorClass"/>    
  8. id>    
  9.   
  10. (1)name (可选): 标识属性的名字。    
  11. (2)type (可选): 标识Hibernate类型的名字。    
  12. (3)column (可选 - 默认为属性名): 主键字段的名字。    
  13. (4)unsaved-value (可选 - 默认为null): 一个特定的标识属性值,用来标志该实例是刚刚创建的,尚未保存。这可以把这种实例和从以前的session中装载过(可能又做过修改--译者注)但未再次持久化的实例区分开来。    
  14. (5)access (可选 - 默认为property): Hibernate用来访问属性值的策略。 如果 name属性不存在,会认为这个类没有标识属性。   
  15.     
  16. unsaved-value 属性很重要!如果你的类的标识属性不是默认为null的,你应该指定正确的默认值。    
  17. 还有一个另外的<composite-id>声明可以访问旧式的多主键数据。我们强烈不鼓励使用这种方式。   

 

 
主键生成策略generator
  1. 必须声明的子元素是一个Java类的名字,用来为该持久化类的实例生成唯一的标识。如果这个生成器实例需要某些配置值或者初始化参数,用 元素来传递。    
  2.   
  3. "id" type="long" column="uid" unsaved-value="0">      
  4. class="net.sf.hibernate.id.TableHiLoGenerator">     
  5.     "table">uid_table    
  6.     "column">next_hi_value_column    
  7.      
  8.   
  9. 所有的生成器都实现net.sf.hibernate.id.IdentifierGenerator接口    

 

 
Hibernate内置的主键生成策略
  1. increment(递增)    
  2. 用于为longshort或者int类型生成唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。    
  3. identity    
  4. 对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。返回的标识符是longshort 或者int类型的。    
  5. sequence (序列)    
  6. 在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence),而在Interbase中使用生成器(generator)。返回的标识符是longshort或者 int类型的。    
  7. hilo (高低位)    
  8. 使用一个高/低位算法来高效的生成longshort或者 int类型的标识符。给定一个表和字段(默认分别是是hibernate_unique_key 和next_hi)作为高位值得来源。高/低位算法生成的标识符只在一个特定的数据库中是唯一的。在使用JTA获得的连接或者用户自行提供的连接中,不要使用这种生成器。    
  9. seqhilo(使用序列的高低位)    
  10. 使用一个高/低位算法来高效的生成longshort或者 int类型的标识符,给定一个数据库序列(sequence)的名字。    
  11. uuid.hex    
  12. 用一个128-bit的UUID算法生成字符串类型的标识符。在一个网络中唯一(使用了IP地址)。UUID被编码为一个3216进制数字的字符串。    
  13. uuid.string    
  14. 使用同样的UUID算法。UUID被编码为一个16个字符长的任意ASCII字符组成的字符串。不能使用在PostgreSQL数据库中    
  15. native(本地)    
  16. 根据底层数据库的能力选择identity, sequence 或者hilo中的一个。    
  17. assigned(程序设置)    
  18. 让应用程序在save()之前为对象分配一个标示符。    
  19. foreign(外部引用)    
  20. 使用另外一个相关联的对象的标识符。和联合一起使用。    

 

 
基本类型-property
  1. 元素为类声明了一个持久化的,JavaBean风格的属性。    
  2.   
  3. "propertyName" (1)    
  4. column="column_name" (2)   
  5.  type="typename" (3)    
  6. update="true|false" (4)    
  7. insert="true|false" (4)    
  8. formula="arbitrary SQL expression" (5)    
  9. access="field|property|ClassName" (6) />    
  10.   
  11. (1)name: 属性的名字,以小写字母开头。   
  12.     
  13. (2)column (可选 - 默认为属性名字): 对应的数据库字段名。   
  14.   
  15. (3)type (可选): 一个Hibernate类型的名字。   
  16.     
  17. (4)update, insert (可选 - 默认为 true) :表明在用于UPDATE 和/或 INSERT的SQL语句中是否包含这个字段。这二者如果都设置为false则表明这是一个“外源性(derived)”的属性,它的值来源于映射到同一个(或多个)字段的某些其他属性,或者通过一个trigger(触发器),或者其他程序。   
  18.     
  19. (5)formula (可选): 一个SQL表达式,定义了这个计算(computed) 属性的值。计算属性没有和它对应的数据库字段。    
  20.   
  21. (6)access (可选 - 默认值为 property): Hibernate用来访问属性值的策略。    
  22.   
  23. typename可以是如下几种:    
  24. Hibernate基础类型之一(比如:integer, string, character,date, timestamp, float, binary, serializable, object, blob)。    
  25.   
  26. 一个Java类的名字,这个类属于一种默认基础类型 (比如: intfloat,char, java.lang.String, java.util.Date, java.lang.Integer, java.sql.Clob)。    
  27.   
  28. 一个PersistentEnum的子类的名字。(比如:. eg.Color)。   
  29.     
  30. 一个可以序列化的Java类的名字。    
  31.   
  32. 一个自定义类型的类的名字。(比如: com.illflow.type.MyCustomType)。   
  33.   
  34. 如果你没有指定类型,Hibernarte会使用反射来得到这个名字的属性,以此来猜测正确的Hibernate类型。Hibernate会对属性读取器(getter方法)的返回类进行解释,按照规则2,3,4的顺序。然而,这并不足够。 在某些情况下你仍然需要type属性。(比如,为了区别Hibernate.DATE和Hibernate.TIMESTAMP,或者为了指定一个自定义类型。)    
  35.   
  36. access属性用来让你控制Hibernate如何在运行时访问属性。在默认情况下,Hibernate会使用属性的get/set方法对。如果你指明access="field",Hibernate会忽略get/set方法对,直接使用反射来访问成员变量。你也可以指定你自己的策略,这就需要你自己实现net.sf.hibernate.property.PropertyAccessor接口,再在access中设置你自定义策略类的名字。   

 

 
自定义类-many-to-one
  1. 通过many-to-one元素,可以定义一种常见的与另一个持久化类的关联。这种关系模型是多对一关联。(实际上是一个对象引用。)    
  2.   
  3. "propertyName" (1)    
  4. column="column_name" (2)    
  5. class="ClassName" (3)    
  6. cascade="all|none|save-update|delete" (4)    
  7. outer-join="true|false|auto" (5)    
  8. update="true|false" (6)    
  9. insert="true|false" (6)    
  10. property-ref="propertyNameFromAssociatedClass" (7) access="field|property|ClassName" (8) />    
  11.   
  12. (1)name: 属性名。    
  13.   
  14. (2)column (可选): 字段名。    
  15.   
  16. (3)class (可选 - 默认是通过反射得到属性类型): 关联的类的名字。   
  17.   
  18. (4)cascade(级联)(可选): 指明哪些操作会从父对象级联到关联的对象   
  19.     
  20. (5)outer-join(外连接) (可选 - 默认为 自动): 当设置Hibernate.use_outer_join的时候,对这个关联允许外连接抓取。    
  21.   
  22. (6)update, insert (可选 - defaults to true) 指定对应的字段是否在用于UPDATE 和/或 INSERT的SQL语句中包含。如果二者都是false,则这是一个纯粹的“外源性(derived)”关联,它的值是通过映射到同一个(或多个)字段的某些其他属性得到的,或者通过trigger(除法器),或者是其他程序。    
  23. (7)property-ref: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。如果没有指定,会使用对方关联类的主键。    
  24.   
  25. (8)access (可选 - 默认是 property): Hibernate用来访问属性的策略。 cascade 属性允许下列值: all, save-update, delete, none。设置除了none以外的其它值会传播特定的操作到关联的(子)对象中。参见后面的“Lifecycle Objects(自动管理生命周期的对象)”。    
  26.   
  27. outer-join参数允许下列三个不同值:    
  28.   
  29. auto (默认) 使用外连接抓取关联(对象),如果被关联的对象没有代理(proxy)    
  30.   
  31. true 一直使用外连接来抓取关联    
  32.   
  33. false 永远不使用外连接来抓取关联    
  34.   

 

 

 
一个典型的简单many-to-one声明例子
  1. <many-to-one name="product" class="Product" column="PRODUCT_ID"/>    
  2.   
  3.     property-ref属性只应该用来对付老旧的数据库系统,可能出现外键指向对方关联表的是个非主键字段(但是应该是一个惟一关键字)的情况。这是一种十分丑陋的关系模型。比如说,假设Product类有一个惟一的序列号,它并不是主键。(unique属性控制Hibernate通过SchemaExport工具生成DDL的过程。)    
  4.   
  5. <property name="serialNumber" unique="true" type="string" column="SERIAL_NUMBER"/>    
  6.   
  7. 那么关于OrderItem 的映射可能是:    
  8.   
  9. <many-to-one name="product" property-ref="serialNumber" column="PRODUCT_SERIAL_NUMBER"/>    
  10. 当然,我们决不鼓励这种用法。   

 

 
例子:User-Group
  1. <class name=" com.test.hibernate .User" table="TBL_USER">  
  2.     <id name="id" column="userId"><generator class="native"/>id>  
  3.     <many-to-one name=“group” column=“groupId” outer-join="false"/>  
  4. class>  
  5.   
  6. <class name=" com.test.hibernate .Group" table="TBL_GROUP">  
  7.     <id name="id" column="groupId"><generator class="native"/>id>  
  8. class>  

 

 
自定义类-one-to-one
  1. 持久化对象之间一对一的关联关系是通过one-to-one元素定义的    
  2.   
  3. "propertyName" (1)    
  4. class="ClassName" (2)    
  5. cascade="all|none|save-update|delete" (3)    
  6. constrained="true|false" (4)    
  7. outer-join="true|false|auto" (5)    
  8. property-ref="propertyNameFromAssociatedClass" (6) access="field|property|ClassName" (7) />    
  9.   
  10. (1)name: 属性的名字。   
  11.   
  12. (2)class (可选 - 默认是通过反射得到的属性类型):被关联的类的名字   
  13.     
  14. (3)cascade(级联) (可选) 表明操作是否从父对象级联到被关联的对象。   
  15.     
  16. (4)constrained(约束) (可选) 表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。这个选项影响save()和delete()在级联执行时的先后顺序(也在schema export tool中被使用)。   
  17.   
  18. (5)outer-join(外连接) (可选 - 默认为 自动): 当设置hibernate.use_outer_join的时候,对这个关联允许外连接抓取。   
  19.     
  20. (6)property-ref: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。如果没有指定,会使用对方关联类的主键。   
  21.     
  22. (7)access (可选 - 默认是 property): Hibernate用来访问属性的策略。    
  23.   
  24. 有两种不同的一对一关联:    
  25. 主键关联    
  26. 惟一外键关联    
  27.   
  28. 主键关联不需要额外的表字段;两行是通过这种一对一关系相关联的,那么这两行就共享同样的主关键字值。所以如果你希望两个对象通过主键一对一关联,你必须确认它们被赋予同样的标识值!    
  29.   
  30. 例子:User-IdCard(外键关联)   
  31. <class name=" com.test.hibernate .User" table="TBL_USER">   
  32.     "id" column="userId">class="native"/>   
  33.     "false“ unique=“true”/>  
  34.  
  35.  
  36. " table="TBL_IDCARD">  
  37.     " column="idCardId">native"/>   
  38. class>   

 

 
集合类(Collections)映射
  1. Hibernate可以持久化以下java集合的实例, 包括java.util.Map, java.util.Set, java.util.SortedMap, java.util.SortedSet, java.util.List, 和任何持久实体或值的数组。类型为java.util.Collection或者java.util.List的属性还可以使用“bag”语义来持久。   
  2.   
  3. 警告:用于持久化的集合,除了集合接口外,不能保留任何实现这些接口的类所附加的语义(例如:LinkedHashSet带来的迭代顺序)。所有的持久化集合,实际上都各自按照 HashMap, HashSet, TreeMap, TreeSet 和 ArrayList 的语义直接工作。更深入地说,对于一个包含集合的属性来说,必须把Java类型定义为接口(也就是Map, Set 或者List等),而绝不能是HashMap, TreeSet 或者 ArrayList。存在这个限制的原因是,在你不知道的时候,Hibernate暗中把你的Map, Set 和 List 的实例替换成了它自己的关于Map, Set 或者 List 的实现。(所以在你的程序中,谨慎使用==操作符。)   

 

 
映射集合(Mapping a Collection
  • 第二章.rar (40.9 KB)
  • 描述: 这个能发的帖子好短.给个附件. 原PPT.
  • 下载次数: 34
   
论坛首页 入门讨论版 Hibernate

跳转论坛:
JavaEye推荐