Hibernate 提高性能的方法:(未完)
一、缓存机制:
缓存是介于物理数据源与应用程序之间,是对数据库中的数据复制一份临时放在内存中的容器,其作用是为了减少应用程序对物理数据源访问的次数,从而提高了应用程序的运行性能。Hibernate在进行读取数据的时候,根据缓存机制在相应的缓存中查询,如果在缓存中找到了需要的数据(我们把这称做“缓存命 中"),则就直接把命中的数据作为结果加以利用,避免了大量发送SQL语句到数据库查询的性能损耗。
缓存策略提供商:
提供了HashTable缓存,EHCache,OSCache,SwarmCache,jBoss Cathe2,这些缓存机制,其中EHCache,OSCache是不能用于集群环境(Cluster Safe)的,而SwarmCache,jBoss Cathe2是可以的。HashTable缓存主要是用来测试的,只能把对象放在内存中,EHCache,OSCache可以把对象放在内存(memory)中,也可以把对象放在硬盘(disk)上。
1)一级缓存:Hibernate内置的,不能卸除。
缓存范围:缓存只能被当前Session对象访问。缓存的生命周期依赖于Session的生命周期,当Session被关闭后,缓存也就结束生命周期。通过Session对象的按主键查询方法实现了一级缓存,只能作用在一个Session上,而且只支持按主键查询功能,因此这个功能一般没用。
2)二级缓存:(又称作应用缓存):
Hibernate推出了SessionFactory连接池支持的二级缓存,只要是通过这个连接池取得的连接,都可以按主键查询使用缓存完成。默认这个功能是关闭的,而且此功能还需要第三方支持,Hibernate的缓存支持提供的比较好的是ehcache,同时还支持oscache。
使用缓存必须按照以下步骤来完成:
a) 在hibernate.cfg.xml中设置缓存配置
i. 设置缓存支持类
ii. 使用二级缓存
iii. 使用Query查询缓存
b) 找到要设置缓存的pojo类,打开其映射文
<class name="org.liky.pojo.News" table="NEWS" schema="SUNXUN">
<cache usage="read-only"/>
//这里的read-only表示缓存类型,分为以下四种:
i. Read-only:只读缓存,数据库中的数据不允许进行修改,如果进行修改,就直接提示错误。
ii. Read-write:可读写缓存,数据库中的数据允许修改,修改后缓存数据立刻重新生成
iii. Nonstrict-read-write:不严格的可读写缓存,数据库允许修改,但修改后缓存数据不立刻改变,而是一定时间后再与数据库同步。
iv. Transactional:支持事务处理的缓存,该功能已经与read-write合并了,因此没用了。
c) 加入缓存的配置文件:
<ehcache>
<!--
如果超出范围,硬盘临时文件的保存目录。
-->
<diskStore path="java.io.tmpdir"/>
<!--
maxInMemory - 设置在内存中允许保存的最大对象数量.
eternal - 内存中的数据是否永久保存,一般都设置为false
timeToIdleSeconds - 空闲销毁时间。
timeToLiveSeconds - 缓存的生存时间
overflowToDisk - 如果超过了内存允许的保存范围,是否将数据保存到硬盘上。
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="300"
overflowToDisk="true"
/>
</ehcache>
现在已经完成了二级缓存的配置,可以进行按主键查询的测试。
测试提示缺少支持包的错误,这种错误可以在http://www.findjar.com/index.x 网站下查找对应commons-logging的支持包,并完成下载。
如果想让HQL也包含这个功能,就需要在DAO中设置Query对象允许使用缓存。
public List<News> findAll(int pageNo, int pageSize, String keyword,
String column) throws Exception {
String hql = "FROM News AS n WHERE n." + column + " LIKE ?";
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setCacheable(true);
query.setString(0, "%" + keyword + "%");
query.setFirstResult((pageNo - 1) * pageSize);
query.setMaxResults(pageSize);
return query.list();
}