SlideShare una empresa de Scribd logo
1 de 26
ORM 框架 —— Hibernate3.3

      Hibernate映射元素和类型
使用 XML 文件来配置对象 - 关系
映射
 Hibernate使用 XML 文件来配置对象 - 关系映射,
  有以下优点:
      Hibernate既不会渗透到上层域模型中,也不会渗透到下
       层数据模型中。
      软件开发人员可以独立设计域模型,不必强迫遵守任何
       规范。
      数据库人员可以独立设计数据库,不必强迫遵守任何规
       范
      对象 - 关系映射不依赖于任何程序代码,如果需要修改
       对象 - 关系映射,只需修改 XML 文件,不需要修改任
       何程序,提高了软件的灵活性,并且使维护更加方便。



www.sodi.com.cn
持久化类的属性和访问方法

 持久化类是指其实例需要被 Hibernate持久化到数
  据库中的类。持久化类通常都是域模型中的实体
  域类,符合 JavaB ean 规范。
 Hibernate并不要求持久化类必须实现
  java.io.S erializable接口。
 Hibernate要求持久化类必须提供一个无参构造方法
  。
                         Customer 对象
                  Java        getXXX()
   用户
                   应用                    Hibernate   数据库
   界面
                   程序
                              setXXX()



www.sodi.com.cn
基本类型属性和包装类型属性

 在持久化类中,既可以把属性定义为基本类型,
  也可以定义为包装类型,它们对应相同的 Hibernate
  映射类型(请参考 Hibernate 映射类型对照
  表 .xlsx )。
 基本类型和包装类型各有优缺点。
 基本类型的优点是:使用方便,对于数字类型,
  可以直接进行数学运算;缺点在于无法表达 null
  值。
 包装类型进行数学运算时稍微麻烦一些,但是与
  S QL 数据类型之间具有更直接的对应关系。
 对于持久化类的 OI D ,推荐使用包装类型。
www.sodi.com.cn
Hibernate访问持久化类属性的策略

 在对象 - 关系映射文件中, < property> 元素的
  access 属性用于指定 Hibernate访问持久化类的属性
  的方式。它有两种可选值:
      property :这是默认值,表明 Hibernate通过对应的
       setXXX( ) 和 getXXX( ) 方法来访问类的属性。这是优先推
       荐的方式。
      field :表明 Hibernate运用 Java 反射机制直接访问类的属
       性。




www.sodi.com.cn
在持久化类的访问方法中加入程序逻辑

 在持久化类的访问方法中,可以加入程序逻辑,
  下面举例说明。
      在 Customer 类的 getName( ) 和 setName( ) 方法中加入程序
       逻辑。
      在 Customer 类的 setS ex( ) 方法中加入数据验证逻辑。




www.sodi.com.cn
控制 insert 和 update语句 ( 1)

 Hibernate在初始化阶段,就会根据映射文件的映射
  信息,为所有的持久化类预定义以下 S QL 语句
  insert 语句、 update语句、 delete语句和根据 OI D
  来检索持久化类实例的 select 语句。
  例如 S algrade类的语句如下:
    INSERT    INTO SALGRADE(GRADE, LOSAL, HISAL) VALUES(?, ?, ?);
    UPDATE    SALGRADE SET LOSAL=?, HISAL=?;
    DELETE    FROM SALGRADE WHERE ID=?;
    SELECT    GRADE,LOSAL,HISAL FROM SALGRADE WHERE GRADE=?;




www.sodi.com.cn
控制 insert 和 update语句 ( 2)

 以上 S QL 语句中的问号代表 JDB C P reparedS tatement 中的
  参数。这些 S QL 语句都存放在 S essionFactory 的缓存中,当
  执行 S ession 的 save( ) 、 update( ) 、 delete( ) 和 load( ) 方法时,
  将从缓存中找到相应的预定义 S QL 语句,再把具体的参数
  值绑定到该 S QL 语句中。
 而 HQL 或 QB C 查询对应的 select 语句必须在执行该代码时
  才能动态生成。
 在对象 - 关系映射文件中,通过配置 < class> 和 < property>
  元素的一些属性,可以控制 insert 和 update语句的生成,具
  体参考 Hibernate_Reference中对象 / 关系数据库映射基础
  ( B asic O/R Mapping) 一章。




www.sodi.com.cn
用于控制 insert 和 update语句的映射属性
      映射属性                                  作用
<property> 元素的      false ,在 insert 语句中不包含该字段,即不能被插入 ; 默认值为 true
insert 属性
<property> 元素的      false ,在 update 语句中不包含该字段,即不能被修改 , 默认值为 true
update 属性
<class> 元素的         false ,等价于所有的 <property> 元素的 update 为 false ,即不能
mutable 属性          被修改 , 默认值为 true
<property> 元素的      如果为 true, 表示当更新一个对象时,会动态生成 insert 语句,只能取
dynamic-insert 属性   值不为 null 时,才会包含到 insert 语句中,默认值为 false
<property> 元素的      如果为 true, 表示当更新一个对象时,会动态生成 update 语句,只能
dynamic-update 属性   取值不为 null 时,才会包含到 update 语句中,默认值为 false
<class> 元素的         如果为 true, 所有 <property> 的 dynamic-insert 属性为 true, 表示
dynamic-insert 属性   当更新一个对象时,会动态生成 insert 语句,只能取值不为 null 时,才
                    会包含到 insert 语句中,默认值为 false
<class> 元素的         如果为 true, 所有 <property> 的 dynamic-update 属性为 true, 表
dynamic-update 属性   示当更新一个对象时,会动态生成 insert 语句,只能取值不为 null 时,
                    才会包含到 update 语句中,默认值为 false




www.sodi.com.cn
处理 S QL 引用标识符

  在 S QL 语法中,标识符是指用于为数据库表、视
   图、字段或者索引等命名的字符串,常规标识符
   不包含空格,也不包含特殊字符,因此无需使用
   引号括起来。
  有时候,特别是在遗留数据库中,你会遇到包含
   奇怪字符或者空格的标识符,或者你希望强制区
   分大小写。或者,如果依赖 Hibernate的默认配置
   , Java 中的类名或者属性名可能被自动转化为数
   据库管理系统中不允许的表名或者列名。那么,
   就可以使用引用标识符。
  用反引号括起来是一种方案,但它是 Hibernate的
   一个实现细节,而不是 JPA 规范的一部分,所以
   一般情况下,应该考虑重新命名表名和列名。
www.sodi.com.cn
映射对象标识符

 Java 语言按内存地址来识别或区分同一个类的不同
  对象,而关系数据库按主键值来识别或区分同一
  个表的不同记录。
 Hibernate使用对象标识符( OI D )来建立内存中
  的对象和数据库表中记录的对应关系,对象的
  OI D 和数据库表的主键对应。
 为了保证持久化对象的 OI D 的唯一性和不可变性
  ,应该让 Hibernate,而不是应用程序为 OI D 赋值
  。



www.sodi.com.cn
< id> 元素

 被映射的类 必须 定义对应数据库表主键字段。大
  多数类有一个 JavaB eans 风格的属性, 为每一个实
  例包含唯一的标识。 < id> 元素定义了该属性到
  数据库表主键字段的映射。例如:
     <id name="productGuid" type="java.lang.Integer">
        <column name="ProductGUID" />
        <generator class="native" />
     </id>


 < id> 元素可选的属性可以参考
  Hibernate_Reference。



www.sodi.com.cn
< generator> 子元素

 < generator> 子元素用来设定标识符生成器。
 Hibernate提供了标识符生成器接口
  I dentifierGenerator ,开发者可以通过实现该接口创
  建自己的标识符生成器。
 当然, Hibernate提供了很多内置的实现,接下来
  我们逐个介绍。




www.sodi.com.cn
assigned 标识符生成器

 让应用程序在 save( ) 之前为对象分配一个标示符。
  这是 < generator> 元素没有指定时的默认生成策略
  。
 适用范围:
      由于 assigned 生成标识符的机制不依赖于底层数据库系
       统,因此它适用于所有的数据库系统。
      主键由应用程序生成而非 Hibernate来生成。




www.sodi.com.cn
increm 标识符生成器
      ent

 Hibernate启动时,这个生成器读取表的最大(数字
  )主键列值,并且每次插入一个新行时值就增加
  1 。生成的标识符类型为 long 、 short 或者 int 。
 适用范围:
      由于 increm 生成标识符的机制不依赖于底层数据库系
                    ent
       统,因此它适用于所有的数据库系统。
      适用于只有单个 Hibernate应用进程访问同一个数据库的
       场合,在集群环境下不推荐使用它。
      OI D 必须为 long 、 int 或 short 类型,如果 OI D 定义为
       其他类型,在运行时会抛出
       I dentifierGenerationE xception 。


www.sodi.com.cn
identity 标识符生成器

 I dentity 标识符生成器由底层数据库来负责生成标
  识符,它要求底层数据库将主键定义为自动增长
  字段类型。
 适用范围:
      由于 identity 生成标识符的机制依赖于底层数据库系统
       ,因此,要求底层数据库系统必须支持自动增长字段类
       型。支持自动增长字段类型的数据库包括:
       DB 2 、 MyS QL 、 MS S QL S erver 、 S ybase、 HS QLDB
       和 I nformix 等。
      OI D 必须为 long 、 int 或 short 类型,如果 OI D 定义为
       其他类型,在运行时会抛出
       I dentifierGenerationE xception 。

www.sodi.com.cn
sequence标识符生成器

 sequence标识符生成器利用底层数据库提供的序列
  来生成标识符。
 适用范围:
      由于 sequence生成标识符的机制依赖于底层数据库系统
       的序列,因此,要求底层数据库系统必须支持序列。支
       持序列的数据库包括: Oracle、 DB 2 、 S A P DB 和
       P ostpreS QL 等。
      OI D 必须为 long 、 int 或 short 类型,如果 OI D 定义为
       其他类型,在运行时会抛出
       I dentifierGenerationE xception 。




www.sodi.com.cn
hilo 标识符生成器

 hilo 标识符生成器由 Hibernate按照一种 hign/low 算
  法来生成标识符,它从数据库的特定表的字段中
  获取 hign 值,并通过添加本地的低值被变成唯一
  。
 适用范围:
      由于 hilo 生成标识符的机制不依赖于底层数据库系统,
       因此适用于所有的数据库系统。
      OI D 必须为 long 、 int 或 short 类型,如果 OI D 定义为
       其他类型,在运行时会抛出
       I dentifierGenerationE xception 。
      hign/low 算法生成的标识符只能在一个数据库中保证唯
       一。

www.sodi.com.cn
uuid 标识符生成器

 uuid 标识符生成器使用一个 128 位的全局唯一标
  识符( Universally Unique I dentifier , UUI D )算法
  生成字符串类型的标识符。 UUI D 包含本机的 I P
  地址、本机 JVM 的信息,相对于同一时空中的所
  有机器都是唯一的。
 适用范围:
      uuid 标识符生成器由 Hibernate维护并生成 uuid 值,不依
        赖于底层数据库的实现细节,因而可以适用于所有数据
        库。
      由于 UUI D 的值是完全随机的,因此在数据库中,不能
        确定记录的顺序。
      仅当你全局地需要唯一标识符时才使用这个生成器策略
        ,并且是我们在不使用 JNI 的前提下的能做的最好实现
        了。
www.sodi.com.cn
guid 标识符生成器

 guid 标识符生成器利用底层数据库生成 guid 的函
  数来生成字符串类型的标识符。
 适用范围:
      由于 guid 生成标识符的机制依赖于底层数据库系统,因
       此,要求底层数据库必须支持 guid 。目前支持 guid 的数
       据库有: Oracle、 MS S QL S erver 、 MyS QL 、 S ybase
       等。
      由于 UUI D 的值是完全随机的,因此在数据库中,不能
       确定记录的顺序。
      仅当你全局地需要唯一标识符时才使用这个生成器策略
       。


www.sodi.com.cn
使用 uuid 标识符或 guid 标识符生成器时注
意
 uuid/guid 标识符生成器使用 32 位 16 进制字符串
  ,需要占用更多的空间,索引的效率也比较低,
  因此,一般都会在表中加一个时间类型或是 int 类
  型的索引,可以弥补以 uuid/guid 作为主键带来的
  性能损失。




www.sodi.com.cn
native标识符生成器

 native标识符生成器依据底层数据库对自动生成标
  识符的支持能力,来选择使用 identity 、 sequence或
  hilo 标识符生成器。 native能自动判断底层数据库
  提供的生成标识符的机制。
 适用范围:
      由于 native能根据底层数据库系统的类型,自动选择合
       适的标识符生成器,因此很适合与跨数据库平台开发,
       即同一个 Hibernate应用需要连接多种数据库系统的场合
       。
      OI D 必须为 long 、 int 或 short 类型,如果 OI D 定义为
       其他类型,在运行时会抛出
       I dentifierGenerationE xception 。

www.sodi.com.cn
映射复合(或称联合)主键 —— 嵌入式

 如果表使用联合主键,你可以映射类的多个属性
  为标识符属性。 < com   posite-id> 元素接受 < key-
  property> 属性映射和 < key-m any-to-one> 属性映射
  作为子元素。 例如:
     <composite-id>
             <key-property name="medicareNumber"/>
             <key-property name="dependent"/>
     </composite-id>


 值得注意的是:
      持久化类必须实现 java.io.serializable接口,并重写
       equals( ) 和 hashCode( ) 方法。
      必须初始化持久化类的实例,填充它的标识符属性,再
       load( ) 组合关键字关联的持久状态。
www.sodi.com.cn
映射复合(或称联合)主键 —— 组件式

 映射复合主键的另一种方式是使用一个组件作为一个
  实体类的标识符。 例如:
     <composite-id name="id" class="MedicareId">
             <key-property name="medicareNumber"/>
             <key-property name="dependent"/>
     </composite-id>

 你的组件类必须满足以下要求:
      必须实现 java.io.S erializable接口。
      包含所有 < key-property> 元素指定的属性。
      必须重新实现 equals( ) 和 hashCode( ) 方法 , 始终和组合关键字
       在数据库中的概念保持一致。
 在持久化类中不必定义 < key-property> 元素指定的属
  性,而是定义 id 属性,类型为 MedicareI d 。
www.sodi.com.cn
Dem — 使用 MyE clipse自动化 Hibernate
   o—

 1. 添加 Hibernate支持。
 2. 利用 Hibernate Reverse E ngineering 完成对象 - 关
  系映射文件和 POJO 类的创建。




www.sodi.com.cn
www.sodi.com.cn

Más contenido relacionado

La actualidad más candente (14)

lwdba – 開放原始碼的輕量級資料庫存取程式庫
lwdba – 開放原始碼的輕量級資料庫存取程式庫lwdba – 開放原始碼的輕量級資料庫存取程式庫
lwdba – 開放原始碼的輕量級資料庫存取程式庫
 
JavaScript 技術手冊第 5 章
JavaScript 技術手冊第 5 章JavaScript 技術手冊第 5 章
JavaScript 技術手冊第 5 章
 
Java面试知识
Java面试知识Java面试知识
Java面试知识
 
J2ee经典学习笔记
J2ee经典学习笔记J2ee经典学习笔记
J2ee经典学习笔记
 
第五章:Struts2标签库
第五章:Struts2标签库第五章:Struts2标签库
第五章:Struts2标签库
 
领域驱动设计实践
领域驱动设计实践领域驱动设计实践
领域驱动设计实践
 
千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7
 
4, workflow tables & api
4, workflow tables & api4, workflow tables & api
4, workflow tables & api
 
Java面试题集
Java面试题集Java面试题集
Java面试题集
 
Java相关基础知识
Java相关基础知识Java相关基础知识
Java相关基础知识
 
Sun java
Sun javaSun java
Sun java
 
Js培训
Js培训Js培训
Js培训
 
Java程序员面试之葵花宝典
Java程序员面试之葵花宝典Java程序员面试之葵花宝典
Java程序员面试之葵花宝典
 
SCJP ch09
SCJP ch09SCJP ch09
SCJP ch09
 

Destacado (10)

youth civic engagement in social media
youth civic engagement in social mediayouth civic engagement in social media
youth civic engagement in social media
 
12 hibernate 集合映射
12 hibernate 集合映射12 hibernate 集合映射
12 hibernate 集合映射
 
9 hibernate 一对多关系映射
9 hibernate 一对多关系映射9 hibernate 一对多关系映射
9 hibernate 一对多关系映射
 
16 hibernate criteria查询
16 hibernate criteria查询16 hibernate criteria查询
16 hibernate criteria查询
 
Plan - innovative måter å møte unge på
Plan - innovative måter å møte unge påPlan - innovative måter å møte unge på
Plan - innovative måter å møte unge på
 
10 hibernate 多对多关系映射
10 hibernate 多对多关系映射10 hibernate 多对多关系映射
10 hibernate 多对多关系映射
 
7 hibernate最佳实践
7 hibernate最佳实践7 hibernate最佳实践
7 hibernate最佳实践
 
15 hibernate hql查询2
15 hibernate hql查询215 hibernate hql查询2
15 hibernate hql查询2
 
VG og unge brukere
VG og unge brukere VG og unge brukere
VG og unge brukere
 
Kommune + unge + sosiale medier = sant
Kommune + unge + sosiale medier = santKommune + unge + sosiale medier = sant
Kommune + unge + sosiale medier = sant
 

Similar a 3 hibernate映射元素和类型

Ecma script edition5-小试
Ecma script edition5-小试Ecma script edition5-小试
Ecma script edition5-小试
lydiafly
 
前端基础知识回顾
前端基础知识回顾前端基础知识回顾
前端基础知识回顾
Wu tianhao
 
Struts+Spring+Hibernate整合教程
Struts+Spring+Hibernate整合教程Struts+Spring+Hibernate整合教程
Struts+Spring+Hibernate整合教程
yiditushe
 
Struts+Spring+Hibernate整合教程
Struts+Spring+Hibernate整合教程Struts+Spring+Hibernate整合教程
Struts+Spring+Hibernate整合教程
appollo0312
 
中远公司 Java培训资料
中远公司  Java培训资料中远公司  Java培训资料
中远公司 Java培训资料
yiditushe
 
Spring 2.x 中文
Spring 2.x 中文Spring 2.x 中文
Spring 2.x 中文
Guo Albert
 
Essential oracle security internal for dba
Essential oracle security internal for dbaEssential oracle security internal for dba
Essential oracle security internal for dba
maclean liu
 
4 hibernate对象管理和缓存结构
4 hibernate对象管理和缓存结构4 hibernate对象管理和缓存结构
4 hibernate对象管理和缓存结构
Zelin Wang
 

Similar a 3 hibernate映射元素和类型 (20)

Mybatis学习培训
Mybatis学习培训Mybatis学习培训
Mybatis学习培训
 
Google protocol buffers简析
Google protocol buffers简析Google protocol buffers简析
Google protocol buffers简析
 
Ecma script edition5-小试
Ecma script edition5-小试Ecma script edition5-小试
Ecma script edition5-小试
 
Servlet & JSP 教學手冊第二版 - 第 7 章:使用 JSTL
Servlet & JSP 教學手冊第二版 - 第 7 章:使用 JSTLServlet & JSP 教學手冊第二版 - 第 7 章:使用 JSTL
Servlet & JSP 教學手冊第二版 - 第 7 章:使用 JSTL
 
前端基础知识回顾
前端基础知识回顾前端基础知识回顾
前端基础知识回顾
 
Ibatis技术讲座
Ibatis技术讲座Ibatis技术讲座
Ibatis技术讲座
 
Struts+Spring+Hibernate整合教程
Struts+Spring+Hibernate整合教程Struts+Spring+Hibernate整合教程
Struts+Spring+Hibernate整合教程
 
Struts+Spring+Hibernate整合教程
Struts+Spring+Hibernate整合教程Struts+Spring+Hibernate整合教程
Struts+Spring+Hibernate整合教程
 
山頂洞人日記 - 回歸到最純樸的開發
山頂洞人日記 -  回歸到最純樸的開發山頂洞人日記 -  回歸到最純樸的開發
山頂洞人日記 - 回歸到最純樸的開發
 
中远公司 Java培训资料
中远公司  Java培训资料中远公司  Java培训资料
中远公司 Java培训资料
 
Kid171 chap03 traditional Chinese Version
Kid171 chap03 traditional Chinese VersionKid171 chap03 traditional Chinese Version
Kid171 chap03 traditional Chinese Version
 
Postgre sql intro 0
Postgre sql intro 0Postgre sql intro 0
Postgre sql intro 0
 
Linux c++ 编程之链接与装载 -提高篇--v0.3--20120509
Linux c++ 编程之链接与装载 -提高篇--v0.3--20120509Linux c++ 编程之链接与装载 -提高篇--v0.3--20120509
Linux c++ 编程之链接与装载 -提高篇--v0.3--20120509
 
Metadata4shenzhen Final
Metadata4shenzhen FinalMetadata4shenzhen Final
Metadata4shenzhen Final
 
Exodus2 大局观
Exodus2 大局观Exodus2 大局观
Exodus2 大局观
 
Kissy design
Kissy designKissy design
Kissy design
 
Spring 2.x 中文
Spring 2.x 中文Spring 2.x 中文
Spring 2.x 中文
 
开源应用日志收集系统
开源应用日志收集系统开源应用日志收集系统
开源应用日志收集系统
 
Essential oracle security internal for dba
Essential oracle security internal for dbaEssential oracle security internal for dba
Essential oracle security internal for dba
 
4 hibernate对象管理和缓存结构
4 hibernate对象管理和缓存结构4 hibernate对象管理和缓存结构
4 hibernate对象管理和缓存结构
 

Más de Zelin Wang

14 hibernate hql查询1
14 hibernate hql查询114 hibernate hql查询1
14 hibernate hql查询1
Zelin Wang
 
13 hibernate 继承映射
13 hibernate 继承映射13 hibernate 继承映射
13 hibernate 继承映射
Zelin Wang
 
11 hibernate 组件映射
11 hibernate 组件映射11 hibernate 组件映射
11 hibernate 组件映射
Zelin Wang
 
6 事务和并发控制
6 事务和并发控制6 事务和并发控制
6 事务和并发控制
Zelin Wang
 
2 hibernate核心api
2 hibernate核心api2 hibernate核心api
2 hibernate核心api
Zelin Wang
 
8 hibernate 一对一关系映射
8 hibernate 一对一关系映射8 hibernate 一对一关系映射
8 hibernate 一对一关系映射
Zelin Wang
 
01 orm概述及持久化介绍
01 orm概述及持久化介绍01 orm概述及持久化介绍
01 orm概述及持久化介绍
Zelin Wang
 

Más de Zelin Wang (7)

14 hibernate hql查询1
14 hibernate hql查询114 hibernate hql查询1
14 hibernate hql查询1
 
13 hibernate 继承映射
13 hibernate 继承映射13 hibernate 继承映射
13 hibernate 继承映射
 
11 hibernate 组件映射
11 hibernate 组件映射11 hibernate 组件映射
11 hibernate 组件映射
 
6 事务和并发控制
6 事务和并发控制6 事务和并发控制
6 事务和并发控制
 
2 hibernate核心api
2 hibernate核心api2 hibernate核心api
2 hibernate核心api
 
8 hibernate 一对一关系映射
8 hibernate 一对一关系映射8 hibernate 一对一关系映射
8 hibernate 一对一关系映射
 
01 orm概述及持久化介绍
01 orm概述及持久化介绍01 orm概述及持久化介绍
01 orm概述及持久化介绍
 

3 hibernate映射元素和类型

  • 1. ORM 框架 —— Hibernate3.3 Hibernate映射元素和类型
  • 2. 使用 XML 文件来配置对象 - 关系 映射  Hibernate使用 XML 文件来配置对象 - 关系映射, 有以下优点:  Hibernate既不会渗透到上层域模型中,也不会渗透到下 层数据模型中。  软件开发人员可以独立设计域模型,不必强迫遵守任何 规范。  数据库人员可以独立设计数据库,不必强迫遵守任何规 范  对象 - 关系映射不依赖于任何程序代码,如果需要修改 对象 - 关系映射,只需修改 XML 文件,不需要修改任 何程序,提高了软件的灵活性,并且使维护更加方便。 www.sodi.com.cn
  • 3. 持久化类的属性和访问方法  持久化类是指其实例需要被 Hibernate持久化到数 据库中的类。持久化类通常都是域模型中的实体 域类,符合 JavaB ean 规范。  Hibernate并不要求持久化类必须实现 java.io.S erializable接口。  Hibernate要求持久化类必须提供一个无参构造方法 。 Customer 对象 Java getXXX() 用户 应用 Hibernate 数据库 界面 程序 setXXX() www.sodi.com.cn
  • 4. 基本类型属性和包装类型属性  在持久化类中,既可以把属性定义为基本类型, 也可以定义为包装类型,它们对应相同的 Hibernate 映射类型(请参考 Hibernate 映射类型对照 表 .xlsx )。  基本类型和包装类型各有优缺点。  基本类型的优点是:使用方便,对于数字类型, 可以直接进行数学运算;缺点在于无法表达 null 值。  包装类型进行数学运算时稍微麻烦一些,但是与 S QL 数据类型之间具有更直接的对应关系。  对于持久化类的 OI D ,推荐使用包装类型。 www.sodi.com.cn
  • 5. Hibernate访问持久化类属性的策略  在对象 - 关系映射文件中, < property> 元素的 access 属性用于指定 Hibernate访问持久化类的属性 的方式。它有两种可选值:  property :这是默认值,表明 Hibernate通过对应的 setXXX( ) 和 getXXX( ) 方法来访问类的属性。这是优先推 荐的方式。  field :表明 Hibernate运用 Java 反射机制直接访问类的属 性。 www.sodi.com.cn
  • 6. 在持久化类的访问方法中加入程序逻辑  在持久化类的访问方法中,可以加入程序逻辑, 下面举例说明。  在 Customer 类的 getName( ) 和 setName( ) 方法中加入程序 逻辑。  在 Customer 类的 setS ex( ) 方法中加入数据验证逻辑。 www.sodi.com.cn
  • 7. 控制 insert 和 update语句 ( 1)  Hibernate在初始化阶段,就会根据映射文件的映射 信息,为所有的持久化类预定义以下 S QL 语句 insert 语句、 update语句、 delete语句和根据 OI D 来检索持久化类实例的 select 语句。 例如 S algrade类的语句如下: INSERT INTO SALGRADE(GRADE, LOSAL, HISAL) VALUES(?, ?, ?); UPDATE SALGRADE SET LOSAL=?, HISAL=?; DELETE FROM SALGRADE WHERE ID=?; SELECT GRADE,LOSAL,HISAL FROM SALGRADE WHERE GRADE=?; www.sodi.com.cn
  • 8. 控制 insert 和 update语句 ( 2)  以上 S QL 语句中的问号代表 JDB C P reparedS tatement 中的 参数。这些 S QL 语句都存放在 S essionFactory 的缓存中,当 执行 S ession 的 save( ) 、 update( ) 、 delete( ) 和 load( ) 方法时, 将从缓存中找到相应的预定义 S QL 语句,再把具体的参数 值绑定到该 S QL 语句中。  而 HQL 或 QB C 查询对应的 select 语句必须在执行该代码时 才能动态生成。  在对象 - 关系映射文件中,通过配置 < class> 和 < property> 元素的一些属性,可以控制 insert 和 update语句的生成,具 体参考 Hibernate_Reference中对象 / 关系数据库映射基础 ( B asic O/R Mapping) 一章。 www.sodi.com.cn
  • 9. 用于控制 insert 和 update语句的映射属性 映射属性 作用 <property> 元素的 false ,在 insert 语句中不包含该字段,即不能被插入 ; 默认值为 true insert 属性 <property> 元素的 false ,在 update 语句中不包含该字段,即不能被修改 , 默认值为 true update 属性 <class> 元素的 false ,等价于所有的 <property> 元素的 update 为 false ,即不能 mutable 属性 被修改 , 默认值为 true <property> 元素的 如果为 true, 表示当更新一个对象时,会动态生成 insert 语句,只能取 dynamic-insert 属性 值不为 null 时,才会包含到 insert 语句中,默认值为 false <property> 元素的 如果为 true, 表示当更新一个对象时,会动态生成 update 语句,只能 dynamic-update 属性 取值不为 null 时,才会包含到 update 语句中,默认值为 false <class> 元素的 如果为 true, 所有 <property> 的 dynamic-insert 属性为 true, 表示 dynamic-insert 属性 当更新一个对象时,会动态生成 insert 语句,只能取值不为 null 时,才 会包含到 insert 语句中,默认值为 false <class> 元素的 如果为 true, 所有 <property> 的 dynamic-update 属性为 true, 表 dynamic-update 属性 示当更新一个对象时,会动态生成 insert 语句,只能取值不为 null 时, 才会包含到 update 语句中,默认值为 false www.sodi.com.cn
  • 10. 处理 S QL 引用标识符  在 S QL 语法中,标识符是指用于为数据库表、视 图、字段或者索引等命名的字符串,常规标识符 不包含空格,也不包含特殊字符,因此无需使用 引号括起来。  有时候,特别是在遗留数据库中,你会遇到包含 奇怪字符或者空格的标识符,或者你希望强制区 分大小写。或者,如果依赖 Hibernate的默认配置 , Java 中的类名或者属性名可能被自动转化为数 据库管理系统中不允许的表名或者列名。那么, 就可以使用引用标识符。  用反引号括起来是一种方案,但它是 Hibernate的 一个实现细节,而不是 JPA 规范的一部分,所以 一般情况下,应该考虑重新命名表名和列名。 www.sodi.com.cn
  • 11. 映射对象标识符  Java 语言按内存地址来识别或区分同一个类的不同 对象,而关系数据库按主键值来识别或区分同一 个表的不同记录。  Hibernate使用对象标识符( OI D )来建立内存中 的对象和数据库表中记录的对应关系,对象的 OI D 和数据库表的主键对应。  为了保证持久化对象的 OI D 的唯一性和不可变性 ,应该让 Hibernate,而不是应用程序为 OI D 赋值 。 www.sodi.com.cn
  • 12. < id> 元素  被映射的类 必须 定义对应数据库表主键字段。大 多数类有一个 JavaB eans 风格的属性, 为每一个实 例包含唯一的标识。 < id> 元素定义了该属性到 数据库表主键字段的映射。例如: <id name="productGuid" type="java.lang.Integer"> <column name="ProductGUID" /> <generator class="native" /> </id>  < id> 元素可选的属性可以参考 Hibernate_Reference。 www.sodi.com.cn
  • 13. < generator> 子元素  < generator> 子元素用来设定标识符生成器。  Hibernate提供了标识符生成器接口 I dentifierGenerator ,开发者可以通过实现该接口创 建自己的标识符生成器。  当然, Hibernate提供了很多内置的实现,接下来 我们逐个介绍。 www.sodi.com.cn
  • 14. assigned 标识符生成器  让应用程序在 save( ) 之前为对象分配一个标示符。 这是 < generator> 元素没有指定时的默认生成策略 。  适用范围:  由于 assigned 生成标识符的机制不依赖于底层数据库系 统,因此它适用于所有的数据库系统。  主键由应用程序生成而非 Hibernate来生成。 www.sodi.com.cn
  • 15. increm 标识符生成器 ent  Hibernate启动时,这个生成器读取表的最大(数字 )主键列值,并且每次插入一个新行时值就增加 1 。生成的标识符类型为 long 、 short 或者 int 。  适用范围:  由于 increm 生成标识符的机制不依赖于底层数据库系 ent 统,因此它适用于所有的数据库系统。  适用于只有单个 Hibernate应用进程访问同一个数据库的 场合,在集群环境下不推荐使用它。  OI D 必须为 long 、 int 或 short 类型,如果 OI D 定义为 其他类型,在运行时会抛出 I dentifierGenerationE xception 。 www.sodi.com.cn
  • 16. identity 标识符生成器  I dentity 标识符生成器由底层数据库来负责生成标 识符,它要求底层数据库将主键定义为自动增长 字段类型。  适用范围:  由于 identity 生成标识符的机制依赖于底层数据库系统 ,因此,要求底层数据库系统必须支持自动增长字段类 型。支持自动增长字段类型的数据库包括: DB 2 、 MyS QL 、 MS S QL S erver 、 S ybase、 HS QLDB 和 I nformix 等。  OI D 必须为 long 、 int 或 short 类型,如果 OI D 定义为 其他类型,在运行时会抛出 I dentifierGenerationE xception 。 www.sodi.com.cn
  • 17. sequence标识符生成器  sequence标识符生成器利用底层数据库提供的序列 来生成标识符。  适用范围:  由于 sequence生成标识符的机制依赖于底层数据库系统 的序列,因此,要求底层数据库系统必须支持序列。支 持序列的数据库包括: Oracle、 DB 2 、 S A P DB 和 P ostpreS QL 等。  OI D 必须为 long 、 int 或 short 类型,如果 OI D 定义为 其他类型,在运行时会抛出 I dentifierGenerationE xception 。 www.sodi.com.cn
  • 18. hilo 标识符生成器  hilo 标识符生成器由 Hibernate按照一种 hign/low 算 法来生成标识符,它从数据库的特定表的字段中 获取 hign 值,并通过添加本地的低值被变成唯一 。  适用范围:  由于 hilo 生成标识符的机制不依赖于底层数据库系统, 因此适用于所有的数据库系统。  OI D 必须为 long 、 int 或 short 类型,如果 OI D 定义为 其他类型,在运行时会抛出 I dentifierGenerationE xception 。  hign/low 算法生成的标识符只能在一个数据库中保证唯 一。 www.sodi.com.cn
  • 19. uuid 标识符生成器  uuid 标识符生成器使用一个 128 位的全局唯一标 识符( Universally Unique I dentifier , UUI D )算法 生成字符串类型的标识符。 UUI D 包含本机的 I P 地址、本机 JVM 的信息,相对于同一时空中的所 有机器都是唯一的。  适用范围:  uuid 标识符生成器由 Hibernate维护并生成 uuid 值,不依 赖于底层数据库的实现细节,因而可以适用于所有数据 库。  由于 UUI D 的值是完全随机的,因此在数据库中,不能 确定记录的顺序。  仅当你全局地需要唯一标识符时才使用这个生成器策略 ,并且是我们在不使用 JNI 的前提下的能做的最好实现 了。 www.sodi.com.cn
  • 20. guid 标识符生成器  guid 标识符生成器利用底层数据库生成 guid 的函 数来生成字符串类型的标识符。  适用范围:  由于 guid 生成标识符的机制依赖于底层数据库系统,因 此,要求底层数据库必须支持 guid 。目前支持 guid 的数 据库有: Oracle、 MS S QL S erver 、 MyS QL 、 S ybase 等。  由于 UUI D 的值是完全随机的,因此在数据库中,不能 确定记录的顺序。  仅当你全局地需要唯一标识符时才使用这个生成器策略 。 www.sodi.com.cn
  • 21. 使用 uuid 标识符或 guid 标识符生成器时注 意  uuid/guid 标识符生成器使用 32 位 16 进制字符串 ,需要占用更多的空间,索引的效率也比较低, 因此,一般都会在表中加一个时间类型或是 int 类 型的索引,可以弥补以 uuid/guid 作为主键带来的 性能损失。 www.sodi.com.cn
  • 22. native标识符生成器  native标识符生成器依据底层数据库对自动生成标 识符的支持能力,来选择使用 identity 、 sequence或 hilo 标识符生成器。 native能自动判断底层数据库 提供的生成标识符的机制。  适用范围:  由于 native能根据底层数据库系统的类型,自动选择合 适的标识符生成器,因此很适合与跨数据库平台开发, 即同一个 Hibernate应用需要连接多种数据库系统的场合 。  OI D 必须为 long 、 int 或 short 类型,如果 OI D 定义为 其他类型,在运行时会抛出 I dentifierGenerationE xception 。 www.sodi.com.cn
  • 23. 映射复合(或称联合)主键 —— 嵌入式  如果表使用联合主键,你可以映射类的多个属性 为标识符属性。 < com posite-id> 元素接受 < key- property> 属性映射和 < key-m any-to-one> 属性映射 作为子元素。 例如: <composite-id> <key-property name="medicareNumber"/> <key-property name="dependent"/> </composite-id>  值得注意的是:  持久化类必须实现 java.io.serializable接口,并重写 equals( ) 和 hashCode( ) 方法。  必须初始化持久化类的实例,填充它的标识符属性,再 load( ) 组合关键字关联的持久状态。 www.sodi.com.cn
  • 24. 映射复合(或称联合)主键 —— 组件式  映射复合主键的另一种方式是使用一个组件作为一个 实体类的标识符。 例如: <composite-id name="id" class="MedicareId"> <key-property name="medicareNumber"/> <key-property name="dependent"/> </composite-id>  你的组件类必须满足以下要求:  必须实现 java.io.S erializable接口。  包含所有 < key-property> 元素指定的属性。  必须重新实现 equals( ) 和 hashCode( ) 方法 , 始终和组合关键字 在数据库中的概念保持一致。  在持久化类中不必定义 < key-property> 元素指定的属 性,而是定义 id 属性,类型为 MedicareI d 。 www.sodi.com.cn
  • 25. Dem — 使用 MyE clipse自动化 Hibernate o—  1. 添加 Hibernate支持。  2. 利用 Hibernate Reverse E ngineering 完成对象 - 关 系映射文件和 POJO 类的创建。 www.sodi.com.cn

Notas del editor

  1. 《精通 Hibernate 》第 4 章的小节可以看一下。 之前都是手动配置 Hibernate ,为了方便后续开发,在本章结尾部分,应该讲一下如何使用 MyEclipse 自动化 Hibernate 。 包括:添加 Hibernate 支持、反向工程、自动生成 HibernateDAO 。
  2. 采用 JavaBean ,通过 getter 和 setter ,可以很容易地做到对属性的读 / 写权限进行分离;另外一个优点是借助自省模式,可以简化 Hibernate 通过 Java 反射机制来获得持久化类的访问方法的过程。 在 Hibernate 应用中,持久化类的访问方法有两个调用者(参考《精通 Hibernate 》 P98 那张图): Java 应用程序:调用持久化类对象的 getXXX() 方法,读取信息,把它输出到用户界面。调用持久化类对象的 setXXX() 方法,把用户输入的信息写入到该对象中。 Hibernate :调用持久化类对象的 getXXX() 方法,读取信息,把它保存到数据库。调用持久化类对象的 setXXX() 方法,把从数据库中读出的信息写入该对象中。 值得注意的是 , Java 应用程序不能访问持久化类的 private 类型的 getXXX() 和 setXXX() 方法,而 Hibernate 没有这个限制,它能够访问各种访问级别的 getXXX() 和 setXXX() 方法。 Hibernate 并不要求持久化类必须实现 java.io.Serializable 接口,但是对于采用分布式结构的 Java 应用,当 Java 对象在不同的进程节点之间传输时,这个对象所属的类必须实现 Serializable 接口,此外,在 Java Web 应用中,如果希望对 HttpSession 中存放的 Java 对象进行持久化,那么这个 Java 对象所属的类也必须实现 Serializable 接口。 Hibernate (和 JPA )要求每个持久化类都有个无参构造函数。 Hibernate 在这个构造函数上使用 Java Reflection API 调用持久化类来实例化对象。构造函数可以使非公共的,但必须至少是包可见( package-visable )的,如果运行时生成的代理要用于性能优化的话。代理生成也要求这个类不做 final 声明。
  3. Hibernate 映射类型 可以参考《 Hibernate 映射类型对照表 .xls 》。 在有些场合,可以用基本类型的默认值来表示属性值是未知的。例如,对于 Customer 类的 int 类型的 age 属性,如果 age 属性为 0 ,可以把它理解为该客户的年龄是未知的。 但在某些场合,如果“ 0” 本身包含业务含义,就无法用“ 0” 来表示未知状态。例如 Student 类有一个 int 类型的 score 属性,表示学生的考试分数。 Int 类型的 score 属性就无法表示这样的业务需求: 如果 score 属性为 null ,表示该学生的成绩是未知的,有可能得了 100 分,也有可能得了 0 分,只是暂时还不知道成绩。 如果 score 属性为 0 ,表示学生考试成绩为 0 分。 在以上情况下,必须使用包装类型。包装类型都是 Java 类,默认值是 null 。 在 SQL 中,所有数据类型的默认值都是 null ,当通过 insert 语句向 STUDENT 表插入一条记录时,如果没有为 SCORE 字段赋值,那么这个字段被自动赋值为 null 。可见, Java 包装类型和 SQL 数据类型之间具有更直接的对应关系。 Hibernate 既支持包装类型,也支持基本类型。开发人员可以根据开发习惯及业务需求来决定使用何种类型。对于持久化类 OID ,推荐使用包装类型,一方面是 Hibernate API 对包装类型提供了友好的支持;另一方面,在默认情况下, Hibernate 根据对象的 OID 是否为 null ,来确定对象是否处于瞬时状态。
  4. property :为持久化类的每个属性提供 setXXX() 和 getXXX() 方法,可以灵活地封装持久化类,提高域模型的透明性。 field :如果 Customer 类没有为 name 属性提供 setName() 和 getName() 方法,就可以把 name 属性设为 field ,使 Hibernate 能直接访问 name 属性。
  5. 参考《精通 Hibernate 》 P100 :在持久化类的访问方法中加入程序逻辑。 注意 : 在第一个示例中, StringTokenizer 是出于兼容性的原因而被保留的遗留类(虽然在新代码中并不鼓励使用它)。建议所有寻求此功能的人使用 String 的 split 方法或 java.util.regex 包。所以应该将孙卫琴书中的例子稍作修改。 在讲这一节的时候,应该突出的是:实体和数据库之间可以是不完全一致的,这种不一致,恰恰通过映射文件来进行缓冲。 针对第二个例子,可以发现 &lt;property&gt; 元素的 access 属性设置为 field 的一种适用情形。 在实际应用中,数据验证逻辑通常是由表示层或者业务逻辑层的过程域对象来实现。在实体域对象中加入数据验证逻辑,主要是便于在软件开发和测试阶段能捕获表示层或者过程域对象应该处理而未处理的异常。提醒开发人员在表示层或者过程域对象中加入相关的数据验证逻辑。
  6. Hibernate 生成动态 SQL 语句的系统开销(如占用 CPU 的时间和占用的内存)很小,因此不会影响应用的运行性能。 如果表中包含许多字段,建议把 dynamic-insert 属性和 dynamic-update 属性都设为 true 。这样,在 insert 和 update 语句中就只包含需要插入或更新的字段,这可以节省数据库执行 SQL 语句的时间,从而提高应用的运行性能。
  7. 默认情况下, Hibernate 没有在生成的 SQL 中用引号把表和列名括起来。这使得 SQL 稍微更容易阅读,也允许你利用这样的事实:大部分 SQL 数据库在比较没有用引号括起来的标识符时都是不区分大小写的。有时候,特别是在遗留数据库中,你会遇到包含奇怪字符或者空格的标识符,或者你希望强制区分大小写。或者,如果依赖 Hibernate 的默认配置, Java 中的类名或者属性名可能被自动转化为数据库管理系统中不允许的表名或者列名。例如, User 类被映射到 USER 表,而它通常是 SQL 数据库中保留的一个关键字。 Hibernate 并不认识任何 DBMS 产品的 SQL 关键字,因此数据库系统在启动或者运行时抛出异常。 如果在映射文件中用反引号把表名或者列名括起来, Hibernate 就会始终在生成的 SQL 中把这个标识符用括号括起来。对于不同的数据库系统,引用标识符有不同的形式。在 MS SQL Server 中,引用标识符的形式为 [IDENTIFIER_NAME] ;在 MySQL 中,引用标识符的形式为’ IDENTIFIER_NAME’ 。但在设置 Hibernate 的映射文件时,可以一律采用’ IDENTIFIER_NAME’ 的形式。 Hibernate 会自动根据 Hibernate 配置文件中的 hibernate.sql_dialect 属性,来生成正确的 SQL 语句。 除了把所有表名和列名用反引号括起来之外,再没有其他办法可以强制 Hibernate 在任何地方使用括起来的标识符了。任何可能的时候,都应该考虑重新命名表名和列名。用反引号括起来是一种方案,但它是 Hibernate 的一个实现细节,而不是 JPA 规范的一部分。
  8. 1. 为了保证 OID 的唯一性和不可变性,应该让 Hibernate ,而不是应用程序来为 OID 赋值。
  9. 在讲标识符生成器的时候,对比一下保存的时候,生成的 SQL 语句包不包含主键字段。
  10. 我们把这种方法称为 embedded (嵌入式) 的组合标识符,在重要的应用中不鼓励使用这种用法。