【SSH网上商城项目实战16】Hibernate的二级缓存处理首页的热门显示

网上商城首页都有热门商品,那么这些商品的点击率是很高的,当用户点击某个热门商品后需要进入商品的详细信息页面,就像淘宝里面那样。那么每次点击都要去后台查询一下该商品的详细信息,就会发送相应的sql语句,每次刷新一下详细页面也会发sql语句,这样的话,性能肯定会受到很大的影响。那么使用Hibernate的二级缓存就可以解决这个问题。

有些人可能会想,我们可以使用重定向,这样的话,在用户第一次访问的时候把信息查出来放到session中,以后每次用户刷新就可以去session中拿了,这样就不用去数据库中查询了,这是有道理的,但是不能解决上面的问题,因为我们要解决的是多用户去访问同一商品,去点击同一商品,重定向只能保证同一用户去点击或刷新。但是二级缓存可以解决这些问题。

我们先详细解说一下基于Hibernate4.3的二级缓存技术,然后再针对本项目做一个具体的配置。

1. Hibernate4.3二级缓存基本配置

与Hibernate3不同,Hibernate4.3的核心包里没有跟缓存相关的类,我们要用二级缓存的话,需要加上缓存的jar包,从官方下载的hibernate-release-4.3.11.Final中的lib/optional/ehcache中有二级缓存所需要的jar包,先要添加到工程中。如下:

然后我们在hibernate.cfg.xml中配置二级缓存相关的配置:

<hibernate-configuration>

	<session-factory>
		<property name="dialect">
			org.hibernate.dialect.MySQLDialect
		</property>

		<property name="show_sql">true</property>

		<!-- 配置二级缓存提供商,注意此处并不是缓存的jar包 -->
		<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

		<mapping class="cn.it.shop.model.Category" />
		<mapping class="cn.it.shop.model.Account" />
		<mapping class="cn.it.shop.model.Product" />

		<!-- 配置哪些类支持缓存,这里主要是显示首页的热门商品,所以Product类支持缓存 -->
		<class-cache usage="read-only" class="cn.it.shop.model.Product"/>
	</session-factory>

</hibernate-configuration>

然后我们开启tomcat服务器,然后访问首页,点击热门商品,后台就没有再发送sql语句了,大家可能会纳闷,难道二级缓存就这么简单?配置上面这两个项就搞定了?其实到现在为止,二级缓存已经生效的原因是它有个默认的配置,在上面那个ehcache-core-2.4.3.jar中有个ehcache-failsafe.xml文件,里面已经有了默认配置,我们等会再具体分析。我们先来分析一下Hibernate的查询策略:

2. Hibernate4.3的查询策略

Hibernate支持两种查询方式:session查询和hql查询。

session中有session.save()  update() delete() get() load()等方法,此方式仅仅操作一条记录,默认不用任何配置就支持二级缓存。因此:read-only配置对session是生效的。在session中如果二级缓存中配置了read-only,则session.update()和delete()操作都会失败,如果想要成功,则需要配置成read-write。但是save()和get()
load()是成功的。

hql:此方式默认是用来操作多条记录,比如list()和executeUpdate() 方法。此方式默认二级缓存的配置包括read-only是无效的。hql的list()查询的是多条记录,直接查询数据库,并将查询的结果交给二级缓存,便于get()和load()的调用。executeUpdate也是不支持二级缓存的,也是直接到数据库更新,Hibernate会保证数据库与缓存同步。注意:hql是没有save()方法的,如果需要插入数据只能调用session.save()方法。

【注】:Hibernate中的一级缓存(默认存在)也称为session级别缓存,不是用来提升性能,而是用来处理事务的;二级缓存为sessionFactory缓存,对所有session都有效,生命周期与sessionFactory相同(sessionFactory是单例,而且项目启动时候就会创建)。

具体的查询策略,我们看下面的这张图:

【注】:图片文字如果太小,可以把图片拖到新的窗口看~

以上就是Hibernate的查询的策略,下面我们来继续看二级缓存的配置。

3. Hibernate4.3二级缓存高级配置

上面提到了,我们之所以在hibernate.cfg.xml中配置了两项就可以使用二级缓存,是因为有个默认的配置,下面我们先来看一下这个默认配置:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">

	<!-- 如果缓存内存溢出,则存储到硬盘空间 -->
    <diskStore path="java.io.tmpdir"/>

    <defaultCache
	    maxElementsInMemory="10000" : <!-- 内存支持的最大对象的数量 -->
	    eternal="false" 	:<!-- 对象是否永久生效,建议为false,这样下面的两个参数才会有效 -->
	    timeToIdleSeconds="60" :<!-- 对象的间隔周期,默认单位为秒。即60秒后如果还没人用这个对象,会提前销毁 -->
	    timeToLiveSeconds="120" :<!-- 对象的生命周期,默认单位为秒 -->
	    overflowToDisk="true"	:<!-- 是否支持溢出到硬盘,建议为true -->
 	    maxElementsOnDisk="10000000" :<!-- 硬盘上支持的最大对象的数量 -->
	    memoryStoreEvictionPolicy="LRU" :<!-- 对象的替换策略 -->
	   />
</ehcache>

关于默认配置的相关解释已经在上面的注释中了,我们现在知道了,正因为这个默认的配置,才使得Hibernate4.3的二级缓存得以正确执行。现在如果我们要自己进行缓存的配置,就需要自己在src目录下新建一个ehcache.xml文件,然后在里面对上面这些配置项重新配置即可。我们接下来要测试一下各个配置,在测试之前,我先把首页显示的情况贴出来,并编个号,等会测试的时候好说明:

以上是首页显示的部分内容,Hibernate已经从数据库中帮我们查出了显示信息,并且已经显示好了。我们将它们编个号,等会我们测试缓存的时候就方便分析了。下面我们开始测试一下上面的缓存配置项:

测试一:测试内存中的对象数量。将配置改成下面情况:

<defaultCache
         maxElementsInMemory="6" <!-- 设置只支持缓存6个 -->
         eternal="true"
         overflowToDisk="false"
         memoryStoreEvictionPolicy="FIFO" :<!-- 先进先出 -->
         />

配置好后,我们重启一下服务器,打开首页,由于配置的是6个,所以缓存中只存了最后查出来的6条记录,也就是编号3-8,我们点击3-8中的任何一个商品进入商品详细页面,注意看后台的控制台没有输出任何查询信息,说明并没有发sql语句,但是当我们点击编号2的商品时,后台发了一条sql语句,即查询了数据库,我们后退再次点击2商品,就没有再发sql语句了,说明已经放到缓存里了,但是缓存只支持6条数据,因为配置的对象替换策略是先进先出,所以刚刚缓存中的编号3被移除,我们点击一下3试试,发了一条sql语句,于是测试完毕,二级缓存执行正常。

测试二:测试对象的生命周期。将配置改成下面的情况:

<defaultCache
     maxElementsInMemory="100"
     eternal="false" <!-- 配成false才能设置下面的生命周期 -->
     timeToIdleSeconds="20"
     timeToLiveSeconds="40"
     overflowToDisk="false"
     memoryStoreEvictionPolicy="FIFO"
     />

上面配置了缓存的时间为40秒,如果20秒没有操作就移除。由于我们配了100条记录,所以上面编号1-8都在缓存里,我们开启服务器后,随便点击一个,比如点击编号8,没有发出sql语句,正常,20秒后,再点击编号8,发了一条sql语句,说明我们配置的生命周期生效了。这里要注意一下,不能配置太短,比如配置10秒,因为tomcat启动也要好几秒,如果配置少了,还没测试可能时间已经到了……那就不行了。

测试三: 测试二级缓存是否支持硬盘存储。

<defaultCache
     maxElementsInMemory="4"
     eternal="false" <!-- 配成false才能设置下面的生命周期 -->
     timeToIdleSeconds="100"
     timeToLiveSeconds="200"
     overflowToDisk="true"  <!-- 配置成true才支持硬盘存储 -->
     memoryStoreEvictionPolicy="FIFO"
     />

我们将支持硬盘存储设置成了true,并将二级缓存最大存储量配置成了4。重启服务器,因为二级缓存最多存4条记录,所以肯定是编号5-8,点击5-8肯定不会发sql语句,但是当我们点击1-4时,也不会发sql语句,因为我们设置了支持硬盘存储,Hibernate将查询结果存在硬盘上了,所以我们也可以直接拿到数据,不需要发sql语句。

测试四: 测试二级缓存的替换策略

<defaultCache
     <!--
      FIFO已经淘汰了,不会再用了……
      LRU:最近最少被访问算法(时间策略),会忽略访问频率,离现在最远时间访问的会被替换掉
      LFU:最近最未使用算法(频率测量),会忽略访问的先后时间,访问频率最少的会被替换掉
     -->
     maxElementsInMemory="3"
     eternal="false" <!-- 配成false才能设置下面的生命周期 -->
     timeToIdleSeconds="100"
     timeToLiveSeconds="200"
     overflowToDisk="false"  <!-- 配置成true才支持硬盘存储 -->
     memoryStoreEvictionPolicy="LFU"
     />

顾名思义,LRU和LFU分别是关注最后访问时间和访问频率的,我们拿LFU来举例子,现在我们设置了最大存储为3条记录,也就是编号6-8,现在我们依次访问编号6三次,编号7两次,编号8一次,都不会发sql语句,我们再访问编号7,发了sql语句,现在编号7存在了缓存里,编号8已经被移除了,因为它访问的次数最少,我们可以再次点击编号8测试一下,发出了sql语句,测试成功。如果是LRU,则刚刚移除的是编号6,因为编号6最早访问的。

到这里,相信大家对二级缓存的使用已经掌握了,二级缓存的测试就到这里。下面针对我们这个网上商城的项目做一下配置。

4. 网上商城项目的实际配置

我们配置二级缓存的最大记录数为1000,设置生命周期为120秒,间隔周期为60秒,支持硬盘存储,并且使用频率优先(LFU)的替换策略,因为用户点击率高的,肯定要放在二级缓存里。

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">

	<!-- 如果缓存内存溢出,则存储到硬盘空间 -->
    <diskStore path="java.io.tmpdir"/>

    <defaultCache
            maxElementsInMemory="1000"
            eternal="false"
            timeToIdleSeconds="60"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            memoryStoreEvictionPolicy="LFU"
            />
</ehcache>

好了,结合网上商城这个项目,Hibernate4.3的二级缓存配置及使用就介绍完了。

(注:到最后提供整个项目的源码下载!欢迎大家收藏或关注)

相关阅读:http://blog.csdn.net/column/details/str2hiberspring.html

_____________________________________________________________________________________________________________________________________________________

-----乐于分享,共同进步!

-----更多文章请看:http://blog.csdn.net/eson_15

时间: 2024-10-14 07:08:44

【SSH网上商城项目实战16】Hibernate的二级缓存处理首页的热门显示的相关文章

【SSH网上商城项目实战22】获取银行图标以及支付页面的显示

从上一节的小demo中我们搞清楚了如何跟易宝对接以及易宝的支付流程.这一节我们来做一下支付页面以及在页面中导入银行图标. 1. 存储银行图标 银行图标一般不会总是去加载,因为这些东西是死的,没必要每次进入支付页面就去加载银行图标,这样性能会受到一定的影响.这让我们联想到了之前的加载首页数据了,其实跟那个道理是一样的,我们可以在项目启动的时候就将银行图标资源加载到application中,后面用到了就直接在application域中取就行了.所以跟原来一样,我们在监听器中加载银行图标.  银行图标

【SSH网上商城项目实战21】从Demo中看易宝支付的流程

这一节我们先写一个简单点的Demo来测试易宝支付的流程,熟悉这个流程后,再做实际的开发,因为是一个Demo,所以我没有考虑一些设计模式的东西,就是直接实现支付功能.实现支付功能需要易宝给我们提供的API.那么问题来了,使用第三方支付平台最主要的一件事就是获取该平台的API,我们首先得获取他们的API以及开发文档,然后才可以做进一步的开发. 1. 获取易宝的API 获取API的第一步,要在易宝上注册一个账号,这个账号是商家的账号,后面买家付款后,会将钱款存入该账号中,然后商家自己提取到银行卡,易宝

【SSH网上商城项目实战27】域名空间的申请和项目的部署及发布

前面陆陆续续的完成了网上商城的一些基本功能,虽然还有很多地方有待完善,但是不影响项目的部署和发布,我们可以先来玩一把,这一节主要介绍下域名空间的申请以及项目的部署和发布流程. 1. 域名空间的申请 作为一个伟大的屌丝,肯定没钱买域名空间,很自然的想到去申请个免费的,现在免费的域名空间也很多,我在福佳jsp技术网上申请了一个试用期是15天的,大家也可以去申请个玩玩,反正作为学习,这已经足够了,当然,如果要长期的肯定要付费的.注册过程我截几个图,如下: 然后下一步,最后开通如下: 建议把上面这些信息

【SSH网上商城项目实战17】购物车基本功能的实现

上一节我们将商品的详细页面做完了,并使用了Hibernate的二级缓存加载详细页面来提高系统的性能.这节我们开始做购物车部分. 1. 添加新的表 首先我们向数据库中添加几张表:用户表.订单状态表.订单表(购物车表)以及购物项表.用户表中存有用户的基本信息,订单状态表中主要存储订单的状态,比如已发货这种,订单表主要存储用户的信息和订单的状态,所以跟用户表和订单状态表关联,购物项表存储某个商品以及所属的订单,所以跟商品表和订单表相关联.具体的表信息见下面的sql语句: /*=============

【SSH网上商城项目实战25】使用java email给用户发送邮件

当用户购买完商品后,我们应该向用户发送一封邮件,告诉他订单已生成之类的信息,邮箱地址是从用户的基本信息中获取,好了,首先我们来看一下Java中发送邮件的方法. 1. java中发送email的方法     在完善这个项目之前,先来回顾一下java中是如何发送邮件的,首先肯定需要发送邮件的jar包:mail.jar,导入到lib目录下,好了,下面我们先写一个普通的java程序来回顾一下java email的知识点: public class SendEmailDemo { public stati

【SSH网上商城项目实战20】在线支付平台的介绍

之前已经完成了首页的显示,用户添加购物车,确认订单等功能,下面就是支付功能的开发了.用户确认了订单后会直接跳转到支付页面进行在线支付,在线支付需要第三方的接口,这一节主要介绍一些关于第三方支付的内容,从下一节开始,我们真正开发在线支付模块. 1. 在线支付介绍 在线支付是指卖方与买方通过因特网上的电子商务网站进行交易时,银行为其提供网上资金结算服务的一种业务.它为企业和个人提供了一个安全.快捷.方便的电子商务应用环境和网上资金结算工具.在线支付不仅帮助企业实现了销售款项的快速归集,缩短收款周期,

【SSH网上商城项目实战14】商城首页UI的设计

前面我们利用EasyUI和SSH搭建好了后台的基本框架,做好了后台的基本功能,包括对商品类别的管理和商品的管理等,这一节我们开始搭建前台页面. 做首页的思路:假设现在商品的业务逻辑都有了,首先我们需要创建一个监听器,在项目启动时将首页的数据查询出来放到application里,即在监听器里调用后台商品业务逻辑的方法. 1.  首页商品显示逻辑 在首页,我们只显示商品热点类别中的前几个商品,比如热点类别有儿童休闲类,女性休闲类,男性休闲类,那我们会有三个板块来显示不同的商品类,每个类别里再显示几个

【SSH网上商城项目实战10】商品类基本模块的搭建

前面我们完成了与商品类别相关的业务逻辑,接下来我们开始做具体商品部分. 1. 数据库建表并映射Model 首先我们在数据库中新建一张表,然后使用逆向工程将表映射成Model类,表如下: /*=============================*/ /* Table: 商品表结构 */ /*=============================*/ create table product ( /* 商品编号,自动增长 */ id int primary key not null aut

【SSH网上商城项目实战29】使用JsChart技术在后台显示商品销售报表

这个项目终于接近尾声了,注册功能我就不做了,关于注册功能我的另一篇博客详细的介绍了一下注册的表单验证,可以直接把功能加到本项目中,修改一下相关的跳转即可,就不再做了.另外,目前这个项目只有action层和service层,dao层我还没抽取,做完这个报表,我把dao层抽取一下,再对整个项目做个总结,差不多就可以上传源码了,到时候欢迎大家下载~ 这一节主要做一下最后一个功能:使用JsChart这个工具来显示商品的销售报表,JsChart是很好用的一款制作报表的工具,之所以好用,是因为它的官方实例做