- 浏览: 3008824 次
- 性别:
- 来自: 河南
文章分类
- 全部博客 (340)
- Java综合 (26)
- 程序人生 (53)
- RIA-ExtJS专栏 (18)
- RIA-mxGraph专栏 (4)
- RIA-Flex4专栏 (43)
- 框架-Spring专栏 (16)
- 框架-持久化专栏 (22)
- 框架-Struts2专栏 (11)
- 框架-Struts专栏 (12)
- SQL/NOSQL (12)
- 报表/图表 (2)
- 工作流 (5)
- XML专栏 (4)
- 日常报错解决方案 (5)
- Web前端-综合 (12)
- Web/JSP (14)
- Web前端-ajax专栏 (14)
- Web前端-JQuery专栏 (9)
- IDE技巧 (6)
- FILE/IO (14)
- 远程服务调用 (2)
- SSO单点登录 (2)
- 资源分享 (22)
- 云计算 (1)
- 项目管理 (3)
- php专栏 (1)
- Python专栏 (2)
- Linux (1)
- 缓存系统 (1)
- 队列服务器 (1)
- 网络编程 (0)
- Node.js (1)
最新评论
-
hui1989106a:
我的也不能解压,360和好压都试了,都不行
《Spring in Action》完整中文版分享下载 -
temotemo:
这些example有些过时了,官方建议使用HBase-1.0 ...
Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询 -
zy8102:
非常感谢~
HeadFirst系列之七:《深入浅出SQL》原版高清PDF电子书分享下载 -
zy8102:
重命名了一下搞定了
HeadFirst系列之七:《深入浅出SQL》原版高清PDF电子书分享下载 -
zy8102:
为什么下载以后老解压不了呢?
HeadFirst系列之七:《深入浅出SQL》原版高清PDF电子书分享下载
1.缓存概述
缓存(cache)在java应用程序中是一组内存中的集合示例,它保存着永久性存储源(如硬盘上的文件或数据库)中数据的备份,它的读写速度比读写硬盘的速度快。应用程序在运行时直接读写缓存中的数据,只在某些特定时刻按照缓存中的数据来同步更新数据存储源。如果缓存中存放的数据量非常大,也会用硬盘作为缓存的物理介质
缓存的作用就是降低应用程序直接读写永久性数据存储源的频率,从而增强应用的运行性能
缓存的实现不仅需要作为物理介质的硬件(内存),同时还需要用于管理缓存的并发访问和过期等策略的软件
2.缓存范围分类
缓存的范围决定了缓存的声明周期以及可以被谁访问。总共分三类
1)事务范围
事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象形式.缓存的生命周期依赖于事务的生命周期,只有当事务结束时,缓存的生命周期才会结束.事务范围的缓存使用内存作为存储介质,一级缓存就属于事务范围.
2)应用范围(也叫进程范围)
应用程序的缓存可以被应用范围内的所有事务共享访问.缓存的生命周期依赖于应用的生命周期,只有当应用结束时,缓存的生命周期才会结束.应用范围的缓存可以使用内存或硬盘作为存储介质,二级缓存就属于应用范围.
3)集群范围
在集群环境中,缓存被一个机器或多个机器的进程共享,缓存中的数据被复制到集群环境中的每个进程节点,进程间通过远程通信来保证缓存中的数据的一致,缓存中的数据通常采用对象的松散数据形式.
对大多数应用来说,应该慎重地考虑是否需要使用集群范围的缓存,因为访问的速度不一定回避直接访问数据库数据的速度快很多
3.缓存的并发访问策略
当多个并发的失误同时访问持久化层的缓存的相同数据时,会引发起并发问题,必须采用必要的失误隔离措施
在进程范围或集群范围的缓存,会出现并发问题,因此可以设定一下四种类型的并发访问策略,每一种策略对应一种事务隔离级别。事务型并发访问策略是事务隔离级别最高,只读型的隔离级别最低。事务隔离级别越高,并发性能就越低
1)事务型:仅仅在受管理环境中适用。它提供了Repeatable Read事务隔离级别。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读和不可重复读这类的并发问题。
2)读写型:提供了Read Committed事务隔离级别。仅仅在非集群的环境中适用。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读这类的并发问题。
3)非严格读写型:不保证缓存与数据库中数据的一致性。如果存在两个事务同时访问缓存中相同数据的可能,必须为该数据配置一个很短的数据过期时间,从而尽量避免脏读。对于极少被修改,并且允许偶尔脏读的数据,可以采用这种并发访问策略。
4)只读型:对于从来不会修改的数据,如参考数据,可以使用这种并发访问策略。
Hibernate中的缓存
hibernate中提供两级缓存,第一级别是Session级别的缓存,它是属于事务范围的缓存,第二级别的缓存是SessionFactory级别的缓存,它是属于进出呢个范围或集群范围的缓存。这一级别的缓存可以进行配置和更改,并且可以进行动态的加载和卸载。Hibernate还为查询结果提供了一个查询缓存,它依赖于第二级缓存
一级缓存的管理:
Hibernate的一级缓存是由Session提供的,因此它只存在于Session的生命周期中,当程序调用save(),update(),saveorupdate()等方法
及调用查询接口list,filter,iterate时,如session缓存中还不存在相应的对象,Hibernate会把该对象加入到一级缓存中,
当Session关闭的时候该Session所管理的一级缓存也会立即被清除
Hibernate的一级缓存是Session所内置的,不能被卸载,也不能进行任何配置
一级缓存采用的是key-value的Map方式来实现的,在缓存实体对象时,对象的主关键字ID是Map的key,实体对象就是对应的值。所以说,一级缓存是以实体对象为单位进行存储的,在访问的时候使用的是主关键字ID
虽然,Hibernate对一级缓存使用的是自动维护的功能,没有提供任何配置功能,但是可以通过Session中所提供的方法来对一级缓存的管理进行手工干预。Session中所提供的干预方法包括以下两种
●evict()
:用于将某个对象从Session的一级缓存中清除
evict()方法适用于以下二种情况:
1)不需要该对象进行同步的数据更新
2)在批量进行更新与删除时,当更新删除每一个对象后,要释对此对象所占用的内存.
●clear()
:用于将一级缓存中的所有对象全部清除。</p>
<p class=MsoNormal>
在进行大批量数据一次性更新的时候,会占用非常多的内存来缓存被更新的对象。这时就应该阶段性地调用clear()方法来清空一级缓存中的对象,控制一级缓存的大小,以避免产生内存溢出的情况。
Hibernate大批量更新时缓存的处理方法:
(假设我们user表的age有5000条大于0的记录,)
Session session
=SessionFactory.openSession();
Transaction tx
=session.beginTransaction();
Itertaor users=session.find("from User u where
u.age>0").itertaor();//HSL语句就不做解释了
while(user.hasNext()){
User user
=(User)users.next();
user.setAge(user.getAge()+1);
//将本批插入的对象立即写入数据库并释放内存
session.flush();
session.clear();
}
tx.commit();
session.close();
用Hibernate处理大批数据时..都必须先执行5000次的update语句,然后才能更新5000个user
对象..
这样就影响到了操作上的性能....在项目当我们遇到性能与空间的问题时,,,要以性能为主..这也就是说要牺牲空间
所以程序最好跳过Hibernate
API 而直接通过JDBC API来执来...
我们改一下上面的代码:
Session
session=SessionFactory.openSession();
Transaction tx
=session.beginTransaction();
Connection conn
=session.connection();
PreparedStatement pstmt =
conn.prepareStatement("update users set age=age+1 "+"where age
>0");
pstmt.executeUpdate();
tx.commit();
虽说这是通过JDBC
API搞作的..但本质上还是通过Hibernater
Transaction的事务这个接口来声明事务的边界的...
其实最好的解决方法就是以创建存储过程,,用底层的数据库运行..这样性能好,速度快....
我就简单的以Oracle数据库为例子.创建一个名为UserUpdate的存储过程...然后在程序中进行调用...
UserUpdate的存储过程代码:
create or replace procadure UserUpdate(u_age in number) as
begin
update users set age=age+1
where age>u_age;
end;
下面的是在程序中如何调用我们命名的存储过程
Session session =SessionFactory.openSession();
Transaction tx =session.beginTransaction();
Connection conn=session.connection();
String str="{call
UserUpdate(?)}";
CallableStatement cstmt=
conn.prepareCall(str);
cstmt.setInt(1,0);
cstmt.executeUpdate();
tx.commit(); 注意.开源的MySQL中不支持存储过程的..
用JDBC
API的好处是这样的..
它不用把大批量的数据事先加载到内存中,然后再进行更新与修改..所以不会消耗大量内存....
(小程序中是看不出什么差别的..当数据的记录达到一定的数据量的时候自然会发现用Hibernate
API 与JDBC API的差别)
在一个就是只能一条记录进行批量更新..不像Hibernate中更新每一条的..
第一级是Session的缓存。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。第一级缓存是必需的,不允许而且事实上也无法比卸除。在第一级缓存中,持久化类的每个实例都具有唯一的OID。
二级缓存管理
第二级缓存是一个可插拔的的缓存插件,它是由SessionFactory负责管理。由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此第二级缓存是进程范围或者集群范围的缓存。这个缓存中存放的对象的松散数据。第二级对象有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。缓存适配器用于把具体的缓存实现软件与Hibernate集成。第二级缓存是可选的,可以在每个类或每个集合的粒度上配置第二级缓存。
Hibernate的二级缓存策略的一般过程如下:
1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询数据库,一次获得所有的数据对象。
2) 把获得的所有数据对象根据ID放入到第二级缓存中。
3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。
4) 删除、更新、增加数据的时候,同时更新缓存。
Hibernate的二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的Query缓存。
Hibernate的Query缓存策略的过程如下:
1) Hibernate首先根据这些信息组成一个Query Key,Query Key包括条件查询的请求一般信息:SQL, SQL需要的参数,记录范围(起始位置rowStart,最大记录个数maxRows),等。
2) Hibernate根据这个Query Key到Query缓存中查找对应的结果列表。如果存在,那么返回这个结果列表;如果不存在,查询数据库,获取结果列表,把整个结果列表根据Query Key放入到Query缓存中。
3) Query Key中的SQL涉及到一些表名,如果这些表的任何数据发生修改、删除、增加等操作,这些相关的Query Key都要从缓存中清空。
适合存放到二级缓存中的数据有以下四种:
1)很少被修改的数据
2)不是很重要的数据,允许偶尔并发的数据
3)不会被并发反问的数据
4)参考数据,指的是供应用参考的常量数据,它的实例数目有限,它的实例会被许多其他类的实例引用。它的实例极少或从来不会被修改
对于那些常被修改的数据,如财务数据(绝对不允许出现并发)和其他应用共享的数据,这些都不能放到第二级缓存中
常用的缓存插件
Hibernate的二级缓存是一个插件,下面是几种常用的缓存插件
1)EhCache:可作为进程访问的缓存,存放的物理介质可以是内存或硬盘,对hibernate的查询缓存提供了支持
2)OSCache:可作为进程范围的缓存,存放数据的物理介质可以使内存或硬盘,体统丰富的缓存数据过期策略,hibernate的查询缓存提供了支持
3)SwarmCache:可作为集群范围内的缓存,但不支持hibernate查询缓存
4)TreeCache:可作为集群范围内的缓存,支持事务性并发访问策略,对hibernate的查询缓存提供了支持
二级缓存示例
配置一:
hibernate.cfg.xml文件中增加
<!--开启二级缓存-->
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<!--启用查询缓存-->
<property name="hibernate.cache.use_query_cache">true</property>
配置二:
工程项目src文件下新建一个ehcache.xml文件,其内容为
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<diskStore path="java.io.tmpdir" />
<defaultCache maxElementsInMemory="10000" eternal="false" overflowToDisk="true" timeToIdleSeconds="300" timeToLiveSeconds="180" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" />
</ehcache>
配置三:
为了缓存某类的对象,其hbm文件中需添加<cache usage="read-only"/>属性例如:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<class name="com.vogue.bbsphoto.entity.Forum"
table="cdb_forums">
<cache usage="read-only"/>
<id name="ID" column="fid" unsaved-value="null">
<generator class="increment" />
</id>
<property name="name" column="name" type="string" />
<property name="type" column="type" type="string" />
</class>
</hibernate-mapping>
配置四:
为了使用查询缓存,Query必须设置cacheable为true,query.setCacheable(true);
例如dao父类中用于hql查询的方法修改后为:
/**
* 执行hql语句的查询
* @param sql
* @return
*/
public List executeQuery(String hql){
List list = new ArrayList();
Session session = HibernateSessionFactory.currentSession();
Transaction tx = null;
Query query = session.createQuery(hql);
query.setCacheable(true);
try {
tx = session.beginTransaction();
list = query.list();
tx.commit();
} catch (Exception ex) {
ex.printStackTrace();
HibernateSessionFactory.rollbackTransaction(tx);
} finally {
HibernateSessionFactory.closeSession();
}
return list;
}
补充一下:当要缓存的对象处于级联关系中时。如果和他存在级联关系的对象都有属性 <cache
usage="read-only"/>那么,在第一次get后该对象所处的对象图中的所有对象都会保存到hibernate的二级缓存中,在第二次get该对象时,直接从二级缓存中找到所有级联的对象;如果其中某个级联对象没有<cache
usage="read-only"/>属性,则不会被保存到二级缓存中,以后每次get时仍然会执行sql去数据库中找该级联对象
发表评论
-
ibatis常用16条SQL语句
2011-07-29 11:08 26091(1) 输入参数为单个值 ... -
iBATIS与Hibernate的异同
2010-12-30 14:47 3713Hibernate Hibernate是一个开放源代 ... -
iBATIS与Spring整合
2010-12-30 14:34 4881接着iBATIS的入门实例来说,ibatis与Spring的 ... -
Hibernate温习(17)--OpenSessionInView模式
2010-11-11 17:04 4564在WEB应用程序中,视图(JSP或Servlet)可能会通过导 ... -
Hibernate温习(15)--性能优化之抓取策略
2010-11-11 14:51 3522抓取策略(fetching strategy) 是指:当应 ... -
Hibernate温习(14)--性能优化之延迟加载机制
2010-11-11 11:33 1776延迟加载 延迟加载 ... -
Hibernate温习(13)--Hibernate程序性能优化的考虑要点
2010-11-11 10:55 1341本文依照HIBERNATE帮助文档,一些网络书籍及项目经 ... -
Hibernate温习(12)--基于注解方式的各种映射全面总结
2010-11-11 10:43 36001. 使用Hibernate Annotation来做对 ... -
Hibernate温习(11)--多事务并发访问控制
2010-11-11 10:25 7437在并发环境,一个数据库系统会同时为各种各样的客户程序 ... -
Hibernate温习(10)--应用程序中的事务管理
2010-11-11 09:26 1939事务的定义 事务就是指作为单个逻辑工作单元执行的一组数据操作 ... -
Hibernate温习(9)--有关Hibernate升级后注解方式的对象关系映射
2010-11-10 17:06 3341我要说的升级指的是我实际中遇到的,由于我之前的项目中Hiber ... -
Hibernate进行测试时时常会有的错误
2010-11-10 14:31 1502在hibernate程序中,如果使用JUNIT进行测试的话,第 ... -
Hibernate温习(8)--使用JPA
2010-11-10 11:00 2382这次讲的JPA前一篇文章都有所介绍,这里呢就是结合hibern ... -
Hibernate温习(7)--JPA回顾
2010-11-10 10:39 1978什么是JPA JPA(Java Pers ... -
Hibernate温习(6)--单向一对一外键关联映射
2010-11-05 10:24 2617hibernate一对一唯一外键关联映射(单向关联Citize ... -
Hibernate温习(5)--集合属性映射
2010-11-04 22:37 2451Hibernate的集合属性映射 ... -
Hibernate温习(3)--有关session的总结
2010-11-04 17:22 4240说到Hibernate那么最核心的就是它的有关数据库的增删改查 ... -
Hibernate温习(1)--最基础的示例
2010-11-04 14:22 3453有关Spring的知识大部分都已经温习完毕,今天开始转向Hib ... -
ibatis入门实例讲解
2010-10-25 10:39 12993之前大家上网的ibatis官方网站:http://www.i ... -
HIbernate温习(2)--连接池配置总结基于第三方c3p0和proxool
2010-07-26 14:42 3443一直都在用连接池技术,也是个好习惯,但用连接 ...
相关推荐
《深入理解Hibernate配置与映射:hibernate-configuration-3.0.dtd与hibernate-mapping-3.0.dtd解析》 在Java世界里,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。而`hibernate-...
2. **库文件**:包含jar包,如hibernate-core.jar、hibernate-entitymanager.jar等,这些是我们在项目中引入Hibernate时需要用到的依赖库。 3. **文档**:通常包括用户指南、API文档、开发者文档等,这些文档提供了...
- **缓存**: Hibernate的二级缓存可以显著提升性能,通过配置可以缓存查询结果和实体实例。 - **批处理**: 使用批处理更新和插入,可以减少数据库交互次数,提高效率。 - **连接池**: 配置合适的连接池,如...
hibernate-jpa-2.0-api-1.0.1.Final.jar
hibernate-jpa-2.0-api-1.0.1.Final-sources.jar hibernate jpa 源代码
本文将重点探讨`hibernate-core-5.0.11.Final.jar`的核心源码,帮助读者深入理解其内部机制,并提供实用的应用指导。 一、Hibernate Core概述 Hibernate Core是Hibernate框架的基础部分,它包含了ORM的核心功能,...
它们用于优化数据库连接的获取和释放,以及缓存数据,提高性能。 6. **hibernate-commons-annotations**: 提供了通用的注解处理,与JPA的注解配合使用,简化了元数据的定义。 7. **dom4j**和**xml-apis**: 支持XML...
而"hibernate-release-5.0.7.Final"目录则可能包含源码、文档、示例项目等,是深入学习和研究Hibernate的好材料。 总之,Hibernate 5.0.7.Final为Java开发带来了极大的便利,通过传智播客黑马程序员2016版的框架,...
hibernate-commons-annotations-4.0.1.Final.jar
本次我们将深入探讨的版本是`hibernate-release-5.0.0.Final(1)`,这个版本在Hibernate的生命周期中具有重要的地位,它引入了多项新特性和改进,旨在提升开发效率和性能。 一、Hibernate概述 Hibernate是Java领域中...
- **性能优化**:对查询执行、缓存管理等进行了优化,提升了应用程序的运行效率。 - **API改进**:提供更友好的API接口,增强了开发者体验。 3. **核心组件解析**: - **Configuration**:负责配置Hibernate,...
- Cache管理:提供更细粒度的缓存控制,包括第二级缓存和查询缓存的优化。 - Batch处理:支持批量插入、更新和删除操作,提高大数据量操作的性能。 - Event监听器:允许在特定的持久化操作前后执行自定义逻辑,如...
Hibernate支持一级缓存(Session级别的缓存)和二级缓存(SessionFactory级别的缓存)。一级缓存默认开启,提高性能但需注意并发问题;二级缓存可配置第三方缓存实现,如EhCache,用于跨Session的数据共享。 五、...
1. 性能优化:5.3.2.Final版本在性能方面进行了大量优化,包括查询缓存、二级缓存策略以及连接池管理等,提高了数据处理速度和资源利用效率。 2. JPA 2.2支持:该版本全面支持Java Persistence API 2.2规范,引入了...
因为Hibernate在读出hbm.xml文件时需要通过网络读取到hibernate-mapping-3.0.dtd 文件。 如果没有网络不能正常工作。 所以提供上述文件。 以及hibernate-mapping-3.0.dtd,hibernate-configuration-3.0.dtd提供下载...
首先,"hibernate-distribution-3.3.2.GA-dist" 是Hibernate 3.3.2.GA版本的完整发布包,它包含了该版本的所有必需组件。这个压缩包中不仅有运行时所需的jar文件,还包含了详细的API文档——javadoc,这对于开发者...
在"hibernate-cglib-repack-2.1_3.jar"中,CGLIB库已经进行了适当的调整和打包,以适应Hibernate的特定需求,比如对JDK版本的兼容性、性能优化等。 除了懒加载,CGLIB还用于实现Hibernate的拦截器(Interceptor)。...
10. **缓存机制**:Hibernate提供了第一级缓存(Session级别的)和第二级缓存(SessionFactory级别的)以提高性能,减少对数据库的直接访问。此外,还可以集成第三方缓存服务如EHCache。 总之,Hibernate 4.2.4....
hibernate-mapping-3.0.dtd 最新从官网下载,无损无修改
2. 性能优化:3.4.0.GA版本针对查询性能和内存使用进行了优化,提升了整体运行效率。 3. 更强的类型支持:增加了对Java 5新类型(如枚举、注解等)的支持,使得ORM映射更加灵活。 4. 新的持久化模型:支持复合主键、...