【什么是Hibernate?】
*一个框架
*一个Java领域的持久化框架
*一个ORM框架
【对象的持久化】
狭义的理解:“持久化”仅仅指把对象永久保存到数据库中
广义的理解:“持久化”包括和数据库相关的各种操作:
-保存:把对象永久保存到数据库中
-更新:更新数据库中对象(记录)的状态。
-删除:从数据库中删除一个对象。
-查询:根据特定的查询条件,把符合查询条件的一个或多个对
象从数据库加载到内存中。
-加载:根据特定的OID,把一个对象从数据库加载到内存中。
OID:为了在系统中能够找到所需对象,需要为每一个对象分配一个唯一的标识号。在关系数据库中称之为逐渐,而在对象术
语中,则叫做对象标识(Object identifier-OID)。
【ORM】
*ORM(Object/Relation Mapping):对象/关系映射
-ORM主要解决对象-关系的映射
-ORM的思想:讲关系数据库中该表中的记录映射成为对象,以对象的形式展现,程序员可以把对数据库的操作转化为对对
象的操作。
-ORM采用源数据来描述对象-关系映射细节,源数据通常采用XML格式,并且存放在专门的对象-关系映射文件中。
【流行的ORM框架】
*Hibernate:
-非常优秀、成熟的ORM框架。
-完成对象的持久化操作
-Hibernate允许开发者采用面向对象的方式来操作关系数据库。
-消除那些针对特定数据库厂商的SQL代码
*iBatis:
-相对Hibernate灵活高,运行书读快
-开发速度慢,不支持纯粹的面向对象操作,需熟悉sql语句,并且熟练掌握sql语句优化功能
*TopLink
*OJB
【Hibernate配置文件中的两个配置项】
*hbm2ddl.auto:该属性可帮助程序员实现正向工程,即由jav代码生成数据库脚本,进而生成具体的表结构。取值:create |
update | create-drop | vaildate
- create:会根据.hbm.xml文件来生成数据表,但是每次运行都会删除上一次的表,重新生成表,哪怕二次没有任何改变
- create-drop:会根据.hbm.xml文件生成表,但是SessionFactory一关闭,表就自动删除
- update:最常用的属性值,也会根据.hbm.xml文件生成表,单弱.hbm.xml文件和数据库中对应的数据表的表结构不
同,Hibernate将更新数据表结构,但不会删除已有的行和列
- validate:会和数据库中的表进行比较,若.hbm.xml文件中的列在数据表中不存在,则抛出异常
*format_sql:是否将SQL转化为格式良好的SQL。取值为treu | false
【Session概述】
*Session接口是Hibernate想应用程序提供的操纵数据库的最主要的接口,它提供了基本的保存,更新,删除和加载Java对象
的方法。
*Session具有一个缓存,位于缓存中的对象称为持久化对象,它和数据库中的相关记录对应。Session能够在某些事件点,按
照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库,这一过程被称为清理缓存(flush)
*站在持久化的角度,Hibernate把对象分为4种状态:持久化状态,临时状态,游离状态,删除状态。Session的特定方法能
使对象从一个状态转换到另一个状态。
【Session缓存】
*在Session接口的视线中包含一系列的Java集合,这些Java集合构成Session缓存。只要Session实例没有结束生命周期,存
放在它缓存中的对象也不会结束生命周期
*Session缓存可减少Hibernate应用程序访问数据库的频率
【脏检查机制】
*Session利用对象的快照进行脏检查
【清理缓存】
*清理缓存:Session按照缓存中对象的属性变化来同步更新数据库
*默认情况下Session在一下时间点清理缓存:
- 显示调用Session的flush()方法
- 当应用程序调用Translation的commit()方法的时候,该方法先清理缓存,然后向数据库提交事务
- 当应用程序执行一些查询(HQL,Criteria)操作时,如果缓存中持久化对象的属性已经发生了变化,会先清理缓存,以保
证查询结果能够反映持久化对象的最新状态
*Session清理缓存的例外情况:如果对象使用native生成器生成OID,那么当调用Session的save()方法保存对象时,会立即
执行向数据库插入该实体的insert语句。
*commit()和flush()方法的区别:flush进行清理缓存的操作,执行一些列sql语,但不提交事务;commit方法先调用flush()
方法,然后提交事务。提交事务意味着对数据库永久保存下来。
【Hibernate逐渐生成策略】
标识符生成器
increment :用于代理主键。由Hibernate自动以递增方式生成。
identity :适用于代理主键。由底层数据库生成标识符。
sequence :适用于代理主键。Hibernate根据底层数据库的序列生成标识符,这要求底层数据库支持序列。
hilo :适用于代理主键。Hibernate分局high/low算法生成标识符。
seqhilo :适用于代理主键。使用一个高/低位算法来高效的生成long,short或者int类型的标识符。
native :适用于代理主键。根据地岑数据库对自动生成标识符的方式,自动选择identity、sequence或hilo。
uuid.hex :适用于代理主键。Hibernate采用128位的UUID算法生成标识符。
uuid.string:适用于代理主键。UUID被编码成16字符长的字符串。
assigned :适用于自然主键。由Java应用程序负责生成标识符。
foreign :适用于代理主键。使用另外一个相关联的对象的标识符。
【设置清理缓存的时间点】
*若希望改变清理缓存的默认时间点,可以通过Session的setFlushMode()方法设定清理缓存的时间点。
站在持久化的角度,对象可以被分为:临时对象,持久化对象,删除对象,游离对象
【持久化对象的状态】
*临时对象(Transident):
- 在使用代理主键的情况下,OID通常为null
- 不处于Session的缓存中
- 在数据库中没有对应的记录
*持久化对象(也叫“托管”)(Persist):
- OID不为null
- 位于Session缓存中
- 若在数据库中已经有和其对应的记录,持久化对象和数据库中的相关记录对应
- Session在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库
- 在同一个Session实例的缓存中,数据库表中的每条记录只对应唯一的持久化对象
*删除对象(Removed)
- 在数据库中没有和其OID对应的记录
- 不再处于Session缓存中
- 一般情况下,应用程序不该再使用被删除的对象
*游离对象(也叫“托管”)(Detached):
- OID不为null
- 不再处于Session缓存中
- 一般情况下,游离对象是持久化对象转变过来的,因此在数据库中可能还存在与它对应的记录
【对象的状态转换图】
【Session的save()方法】
*Session的save()方法是一个临时对象转变为持久化对象
*Session的save()方法完成以下操作:
- 把News对象加入到Session缓存中,使它进入持久化状态
- 使用映射文件指定的标识符生成器,为持久化对象分配唯一的OID。在使用代理主键的情况下,setId()方法为News对象
设置OID是无效的。
- 计划执行一条insert语句
*Hibernate通过持久化对象的OID来维持它和数据库相关记录的对应关系。当News对象处于持久化状态时,不允许程序睡衣修
改它的ID
*persist()和save()区别:
- 当对一个OID不为Null的对象执行save()方法时,会把该对象以一个新的OID保存到数据库中;但执行persist()方法时会
抛出一个异常。
【Session的get()和load()方法】
*都可以根据给定的OID从数据库中加载一个持久化对象
*区别:
- 当数据库中不存在与OID对应的记录时,load()方法抛出ObjectNotFoundException异常,而get()方法返回null
- 两者采用不同的延迟检索策略
【Session的update()方法】
*Session的update()方法是一个游离对象转变为持久化对象,并且计划执行一条update语句。
*若希望Session仅当修改了News对象属性时,才执行update()语句,可以把映射文件中<class>元素的select-before-update
设为true。该属性的默认值为false
*update()方法关联一个游离对象时,如果在Session的缓存中已经存在相同OID的持久化对象,会抛出异常
*当update()方法关联一个游离对象时,如果在数据库中不存在相应的记录,也会抛出异常。
【Session的saveOrUpdate()方法】
*Session的saveOrUpdate()方法同时包含了save()与update()方法的功能
*判定对象为临时对象的标准
- Java对象的OID为null
- 映射文件中为<id>设置了unsaved-value属性,并且Java对象的OID取值与这个unsaved-value属性值匹配
【Session的merge()方法】
*Session的merge()方法能够把一个游离对象的属性复制到一个持久化对象中。
【Session的delete()方法】
*Session的delete()方法既可以删除一个游离对象,也可以删除一个持久化对象
*Session的delete()方法处理过程
- 计划执行一条delete语句
- 把对象从Session缓存中删除,该对象进入删除状态
*Hibernate的cfg.xml配置文件中有一个hibernate.use_identifier_rollback属性,其默认值为false,若把它设为true,将
改变delete()方法的运行行为:delete()方法会把持久化对象或游离对象的OID设置为null,使他们变为临时对象
【Hibernate的配置文件】
*Hibernate配置文件主要用于配置数据库连接和Hibernate运行时所需的各种属性
*每个Hibernate配置文件对应一个Configuration对象
*Hibernate配置文件可以有两种格式:
- hibernate.properties (资源文件的格式)
- hibernate.cfg.xml
【Hibernate.cfg.xml的常用属性】
*JDBC连接属性
- connection.url:数据库URL
- connection.username:数据库用户名
- connection.password:数据库用户密码
- connection.driver_class:数据库JDBC驱动
- dialect:配置数据库的方言,根据底层的数据库不同产生不同的SQL语句,Hibernate会针对数据库的特性在访问时进行
优化
*C3P0数据库连接池属性
- hibernate.connection.provider_class:该类用来向Hibernate提供JDBC连接
- hibernate.c3p0.max_size:数据库连接池的最大连接数
- hibernate.c3p0.min_size:数据库连接池的最小连接数
- hibernate.c3p0.timeout:数据库连接池中连接对象在多长时间没有使用过后,就应该被销毁
- hibernate.c3p0.max_statements:缓存Statement对象的数量
- hibernate.c3p0.idle_test_period:表示连接池检测线程多长时间检测一次池内的所有链接对象是否超时。连接池本身
不会把自己从连接池中移除,而是专门有一个线程按照一定的时间间隔来做这件事,这个线程通过比较连接对象最后一次被
使用时间和当前时间的时间差来和timeout做对比,进而决定是否销毁这个连接对象。
- hibernate.c3p0.axquire_increment:当数据库连接池中的链接耗尽时,同一时刻获取多少个数据库连接。
- hibernate.c3p0.validate:是否每次连接都验证连接是否可用。
(C3p0是一个可选包)
*其他
- show_sql:是否将运行期生成的SQL输出到日志以供调试。取值true | false
- format_sql:是否将SQL转化为格式良好的SQL。取值true | false
- hbm2ddl.auto:在启动和停止时自动的创建,更新或删除数据库模式。取值create | update | create-drop | validate
- hibernate.jdbc.fetch_size
- hibernate.jdbc.batch_size
【jdbc.fetch_size和jdbc.batch_size】
*hibernate.jdbc.fetch_size:实质是调用Statement.setFetchSize()方法设定JDBC的Statement读取数据的时候每次从数据
库中取出的记录条数。
- 例如一次查询1万条记录,对于Oracle的JDBC驱动来说,是不会一次性把1万条取出来的,而只会去除fetchSize条数,当
结果集遍历完了这些记录以后,再去数据库取fetchSize条数据。因此大大节省了无谓的内存消耗。FetchSize设的越大,读
数据库的次数越少,速度越快;FetchSize设的越小,读数据库的次数越多,速度越慢。Oracle数据库的JDBC驱动默认
的FetchSize=10,是一个保守的设定,根据测试,当FetchSize=50时,性能会提升一倍之多,当FetchSize=100,性能还能继续
提升20%,FetchSize继续增大,性能提升的就不显著了。并不是所有的数据库都支持FetchSize特性,例如MySQL就不支持。
*hibernate.jdbc.batch_size:设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小,类似于设置缓冲区大小
的意思。batchSize越大,批量操作时向数据库发送sql的次数越少,速度就越快。
- 测试结果是当BatchSize=0的时候,使用Hibernate对Oracle数据库删除1万条记录需要25秒,BatchSize=50的时候,删除
仅仅需要5秒!Oracle数据库batchSize=30的时候比较合适。
*一个框架
*一个Java领域的持久化框架
*一个ORM框架
【对象的持久化】
狭义的理解:“持久化”仅仅指把对象永久保存到数据库中
广义的理解:“持久化”包括和数据库相关的各种操作:
-保存:把对象永久保存到数据库中
-更新:更新数据库中对象(记录)的状态。
-删除:从数据库中删除一个对象。
-查询:根据特定的查询条件,把符合查询条件的一个或多个对
象从数据库加载到内存中。
-加载:根据特定的OID,把一个对象从数据库加载到内存中。
OID:为了在系统中能够找到所需对象,需要为每一个对象分配一个唯一的标识号。在关系数据库中称之为逐渐,而在对象术
语中,则叫做对象标识(Object identifier-OID)。
【ORM】
*ORM(Object/Relation Mapping):对象/关系映射
-ORM主要解决对象-关系的映射
--------------------------------
|面向对象概念 |面向关系概念 |
--------------------------------
|类 |表 |
--------------------------------
|对象 |表的行(记录)|
--------------------------------
|属性 |表的列(字段)|
--------------------------------
-ORM的思想:讲关系数据库中该表中的记录映射成为对象,以对象的形式展现,程序员可以把对数据库的操作转化为对对
象的操作。
-ORM采用源数据来描述对象-关系映射细节,源数据通常采用XML格式,并且存放在专门的对象-关系映射文件中。
-----------------------------
|域模型 |
业务逻辑层|(对象,属性,关联,继承和多态)|<------
----------------------------- |
|
--------------- |
| ORM API | |
持久化层 --------------- 参照 -------------------
| ORM 实现 |------------>|对象-关系映射文件|
--------------- |(XML) |
-------------------
---------------------------
数据库层 |关系数据模型 |
|(表,字段,索引,主键和外键)|
---------------------------
【流行的ORM框架】
*Hibernate:
-非常优秀、成熟的ORM框架。
-完成对象的持久化操作
-Hibernate允许开发者采用面向对象的方式来操作关系数据库。
-消除那些针对特定数据库厂商的SQL代码
*iBatis:
-相对Hibernate灵活高,运行书读快
-开发速度慢,不支持纯粹的面向对象操作,需熟悉sql语句,并且熟练掌握sql语句优化功能
*TopLink
*OJB
【Hibernate配置文件中的两个配置项】
*hbm2ddl.auto:该属性可帮助程序员实现正向工程,即由jav代码生成数据库脚本,进而生成具体的表结构。取值:create |
update | create-drop | vaildate
- create:会根据.hbm.xml文件来生成数据表,但是每次运行都会删除上一次的表,重新生成表,哪怕二次没有任何改变
- create-drop:会根据.hbm.xml文件生成表,但是SessionFactory一关闭,表就自动删除
- update:最常用的属性值,也会根据.hbm.xml文件生成表,单弱.hbm.xml文件和数据库中对应的数据表的表结构不
同,Hibernate将更新数据表结构,但不会删除已有的行和列
- validate:会和数据库中的表进行比较,若.hbm.xml文件中的列在数据表中不存在,则抛出异常
*format_sql:是否将SQL转化为格式良好的SQL。取值为treu | false
【Session概述】
*Session接口是Hibernate想应用程序提供的操纵数据库的最主要的接口,它提供了基本的保存,更新,删除和加载Java对象
的方法。
*Session具有一个缓存,位于缓存中的对象称为持久化对象,它和数据库中的相关记录对应。Session能够在某些事件点,按
照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库,这一过程被称为清理缓存(flush)
*站在持久化的角度,Hibernate把对象分为4种状态:持久化状态,临时状态,游离状态,删除状态。Session的特定方法能
使对象从一个状态转换到另一个状态。
【Session缓存】
*在Session接口的视线中包含一系列的Java集合,这些Java集合构成Session缓存。只要Session实例没有结束生命周期,存
放在它缓存中的对象也不会结束生命周期
*Session缓存可减少Hibernate应用程序访问数据库的频率
【脏检查机制】
*Session利用对象的快照进行脏检查
【清理缓存】
*清理缓存:Session按照缓存中对象的属性变化来同步更新数据库
*默认情况下Session在一下时间点清理缓存:
- 显示调用Session的flush()方法
- 当应用程序调用Translation的commit()方法的时候,该方法先清理缓存,然后向数据库提交事务
- 当应用程序执行一些查询(HQL,Criteria)操作时,如果缓存中持久化对象的属性已经发生了变化,会先清理缓存,以保
证查询结果能够反映持久化对象的最新状态
*Session清理缓存的例外情况:如果对象使用native生成器生成OID,那么当调用Session的save()方法保存对象时,会立即
执行向数据库插入该实体的insert语句。
*commit()和flush()方法的区别:flush进行清理缓存的操作,执行一些列sql语,但不提交事务;commit方法先调用flush()
方法,然后提交事务。提交事务意味着对数据库永久保存下来。
【Hibernate逐渐生成策略】
标识符生成器
increment :用于代理主键。由Hibernate自动以递增方式生成。
identity :适用于代理主键。由底层数据库生成标识符。
sequence :适用于代理主键。Hibernate根据底层数据库的序列生成标识符,这要求底层数据库支持序列。
hilo :适用于代理主键。Hibernate分局high/low算法生成标识符。
seqhilo :适用于代理主键。使用一个高/低位算法来高效的生成long,short或者int类型的标识符。
native :适用于代理主键。根据地岑数据库对自动生成标识符的方式,自动选择identity、sequence或hilo。
uuid.hex :适用于代理主键。Hibernate采用128位的UUID算法生成标识符。
uuid.string:适用于代理主键。UUID被编码成16字符长的字符串。
assigned :适用于自然主键。由Java应用程序负责生成标识符。
foreign :适用于代理主键。使用另外一个相关联的对象的标识符。
【设置清理缓存的时间点】
*若希望改变清理缓存的默认时间点,可以通过Session的setFlushMode()方法设定清理缓存的时间点。
|------------------------------------------------------------------------------------|
| 清理缓存的模式 |各种查询方法|Transaction的commit()方法|Session的flush()方法|
|------------------------|------------|-------------------------|--------------------|
|FlushMode.AUTO(默认模式)| 清理 | 清理 | 清理 |
|------------------------|------------|-------------------------|--------------------|
|FlushMode.COMMOT | 不清理 | 清理 | 清理 |
|------------------------|------------|-------------------------|--------------------|
|FlushMode.NEVER | 不清理 | 不清理 | 清理 |
|------------------------------------------------------------------------------------|
站在持久化的角度,对象可以被分为:临时对象,持久化对象,删除对象,游离对象
【持久化对象的状态】
*临时对象(Transident):
- 在使用代理主键的情况下,OID通常为null
- 不处于Session的缓存中
- 在数据库中没有对应的记录
*持久化对象(也叫“托管”)(Persist):
- OID不为null
- 位于Session缓存中
- 若在数据库中已经有和其对应的记录,持久化对象和数据库中的相关记录对应
- Session在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库
- 在同一个Session实例的缓存中,数据库表中的每条记录只对应唯一的持久化对象
*删除对象(Removed)
- 在数据库中没有和其OID对应的记录
- 不再处于Session缓存中
- 一般情况下,应用程序不该再使用被删除的对象
*游离对象(也叫“托管”)(Detached):
- OID不为null
- 不再处于Session缓存中
- 一般情况下,游离对象是持久化对象转变过来的,因此在数据库中可能还存在与它对应的记录
【对象的状态转换图】
---- new语句 -------- 垃圾回收
|起点|------------->|临时状态|------------------------------------------
---- -------- |
get() | save() | |
Load() | saveOrUpdate()| |
Query.list() | persist() | |
Query.uniqueResult()| merge() \/ \/
Query.iterator() | ---------- delete() -------- 垃圾回收 ----
Query.scoll() |---------------->|持久化状态|--------------->|删除状态|----------->|终点|
---------- -------- ----
evict() | /\ /\ /\
close() | |update() | |
clear() | |saveOrUpdate() | |
| |lock() | |
| |merge() delete()| |
\/ | | |
-------- | 垃圾回收 |
|游离状态|------------------------------------------
--------
【Session的save()方法】
*Session的save()方法是一个临时对象转变为持久化对象
*Session的save()方法完成以下操作:
- 把News对象加入到Session缓存中,使它进入持久化状态
- 使用映射文件指定的标识符生成器,为持久化对象分配唯一的OID。在使用代理主键的情况下,setId()方法为News对象
设置OID是无效的。
- 计划执行一条insert语句
*Hibernate通过持久化对象的OID来维持它和数据库相关记录的对应关系。当News对象处于持久化状态时,不允许程序睡衣修
改它的ID
*persist()和save()区别:
- 当对一个OID不为Null的对象执行save()方法时,会把该对象以一个新的OID保存到数据库中;但执行persist()方法时会
抛出一个异常。
【Session的get()和load()方法】
*都可以根据给定的OID从数据库中加载一个持久化对象
*区别:
- 当数据库中不存在与OID对应的记录时,load()方法抛出ObjectNotFoundException异常,而get()方法返回null
- 两者采用不同的延迟检索策略
【Session的update()方法】
*Session的update()方法是一个游离对象转变为持久化对象,并且计划执行一条update语句。
*若希望Session仅当修改了News对象属性时,才执行update()语句,可以把映射文件中<class>元素的select-before-update
设为true。该属性的默认值为false
*update()方法关联一个游离对象时,如果在Session的缓存中已经存在相同OID的持久化对象,会抛出异常
*当update()方法关联一个游离对象时,如果在数据库中不存在相应的记录,也会抛出异常。
【Session的saveOrUpdate()方法】
*Session的saveOrUpdate()方法同时包含了save()与update()方法的功能
*判定对象为临时对象的标准
- Java对象的OID为null
- 映射文件中为<id>设置了unsaved-value属性,并且Java对象的OID取值与这个unsaved-value属性值匹配
【Session的merge()方法】
*Session的merge()方法能够把一个游离对象的属性复制到一个持久化对象中。
【Session的delete()方法】
*Session的delete()方法既可以删除一个游离对象,也可以删除一个持久化对象
*Session的delete()方法处理过程
- 计划执行一条delete语句
- 把对象从Session缓存中删除,该对象进入删除状态
*Hibernate的cfg.xml配置文件中有一个hibernate.use_identifier_rollback属性,其默认值为false,若把它设为true,将
改变delete()方法的运行行为:delete()方法会把持久化对象或游离对象的OID设置为null,使他们变为临时对象
【Hibernate的配置文件】
*Hibernate配置文件主要用于配置数据库连接和Hibernate运行时所需的各种属性
*每个Hibernate配置文件对应一个Configuration对象
*Hibernate配置文件可以有两种格式:
- hibernate.properties (资源文件的格式)
- hibernate.cfg.xml
【Hibernate.cfg.xml的常用属性】
*JDBC连接属性
- connection.url:数据库URL
- connection.username:数据库用户名
- connection.password:数据库用户密码
- connection.driver_class:数据库JDBC驱动
- dialect:配置数据库的方言,根据底层的数据库不同产生不同的SQL语句,Hibernate会针对数据库的特性在访问时进行
优化
*C3P0数据库连接池属性
- hibernate.connection.provider_class:该类用来向Hibernate提供JDBC连接
- hibernate.c3p0.max_size:数据库连接池的最大连接数
- hibernate.c3p0.min_size:数据库连接池的最小连接数
- hibernate.c3p0.timeout:数据库连接池中连接对象在多长时间没有使用过后,就应该被销毁
- hibernate.c3p0.max_statements:缓存Statement对象的数量
- hibernate.c3p0.idle_test_period:表示连接池检测线程多长时间检测一次池内的所有链接对象是否超时。连接池本身
不会把自己从连接池中移除,而是专门有一个线程按照一定的时间间隔来做这件事,这个线程通过比较连接对象最后一次被
使用时间和当前时间的时间差来和timeout做对比,进而决定是否销毁这个连接对象。
- hibernate.c3p0.axquire_increment:当数据库连接池中的链接耗尽时,同一时刻获取多少个数据库连接。
- hibernate.c3p0.validate:是否每次连接都验证连接是否可用。
(C3p0是一个可选包)
*其他
- show_sql:是否将运行期生成的SQL输出到日志以供调试。取值true | false
- format_sql:是否将SQL转化为格式良好的SQL。取值true | false
- hbm2ddl.auto:在启动和停止时自动的创建,更新或删除数据库模式。取值create | update | create-drop | validate
- hibernate.jdbc.fetch_size
- hibernate.jdbc.batch_size
【jdbc.fetch_size和jdbc.batch_size】
*hibernate.jdbc.fetch_size:实质是调用Statement.setFetchSize()方法设定JDBC的Statement读取数据的时候每次从数据
库中取出的记录条数。
- 例如一次查询1万条记录,对于Oracle的JDBC驱动来说,是不会一次性把1万条取出来的,而只会去除fetchSize条数,当
结果集遍历完了这些记录以后,再去数据库取fetchSize条数据。因此大大节省了无谓的内存消耗。FetchSize设的越大,读
数据库的次数越少,速度越快;FetchSize设的越小,读数据库的次数越多,速度越慢。Oracle数据库的JDBC驱动默认
的FetchSize=10,是一个保守的设定,根据测试,当FetchSize=50时,性能会提升一倍之多,当FetchSize=100,性能还能继续
提升20%,FetchSize继续增大,性能提升的就不显著了。并不是所有的数据库都支持FetchSize特性,例如MySQL就不支持。
*hibernate.jdbc.batch_size:设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小,类似于设置缓冲区大小
的意思。batchSize越大,批量操作时向数据库发送sql的次数越少,速度就越快。
- 测试结果是当BatchSize=0的时候,使用Hibernate对Oracle数据库删除1万条记录需要25秒,BatchSize=50的时候,删除
仅仅需要5秒!Oracle数据库batchSize=30的时候比较合适。
<!-- 设定fetchSize -->
<property name="jdbc.fetch_size">100</property>
<!-- 设定batchSize -->
<property name="jdbc.batch_size">30</property>