这篇Blog接着上篇Blog提出的场景进行解决方案的描述:
在一个信息列表中,每个信息的权限有多种情况,比如信息列表中存在A、B、C三条信息,各条信息的权限授予给了(guest,admin)、(guest)、(admin),这个时候要获取guest的信息列表,加入cache需要提高效率的地方就在于避免获取信息列表时需与数据库进行实时的查询,同时要注意,一般来说,系统的信息数据量会是比较的大。
在和江南白衣聊的时候他提出了oscache提供的cache:cache标签的解决方案,开始想了一下觉得不怎么可行,这也是因为自己对cache标签不熟的原因,后来去网上查了一下cache:cache标签的使用,看了后觉得对于解决上面的需求应该是可行的。
关于cache:cache标签的具体用法网上有很多文章,大家可以google查找,我这里主要讲讲它的实现思路,在使用oscache提供的这个标签主要是通过以下方法来实现的
<cache:cache>
// jsp代码
</cache:cache>
中间的jsp代码表明需要被缓存的东西,cache标签还提供了key,refresh,time,duration等等属性,对于上面的需求我们通常想的方案都是做数据库级的缓存,避免频繁实时查询数据库,cache标签这种做法的想法却是从入口开始入手,缓存入口自然也就实现了所需要的效果。
要使用cache标签首先需要明确缓存的jsp代码页面是由哪些关键字可以唯一标识出来的,在上面的需求中我们可以得知可以根据用户Id+当前页数+访问的信息类型的ID来唯一标识该页面,那么我们就可以把这个作为cache的key(默认key为uri加上请求的参数),缓存的过期时间可以设为-1(也就是不过期),这个时候我们就得考虑当信息的权限以及信息的数量变更时缓存是得刷新的,通过refresh属性可以达到这个目的,可以建立一个singleton的类来标识哪些信息ID是需要更新缓存的,refresh属性则通过调用此singleton类来确定是否需要更新缓存,这样的情况下需求中所要的效果就实现了,在这种解决方案中我们需要做的就是在对信息进行管理时调用singleton类来标识此id是需要被更新缓存的,在页面上我们只需要定义出能够唯一标识出需缓存页面部分的唯一key(如果能够通过uri加上请求参数作为唯一标识的情况下就不用定义key了,不过在需要权限过滤的地方一般来说是需要自己定义key的,因为要获取当前的用户ID),调用singleton获取refresh的属性,之后加入cache:cache标签就搞定了。
其实从上面的解决方案中我们可以推测oscache标签的实现思路,非常的简单,和通常我们做缓存的思路都一样,只是它提供了对于缓存的一个很好的处理机制,那就是从入口下手,在第一次运行页面的时候,它通过将生成的html作为value缓存到对应的key中,第二次运行页面时它通过此key去获取html,如无此key则运行jsp代码,同理其实可以将它运行到很多系统的场景中。
ps: 在用了这种解决方案后确实不错,系统的性能提升了很多,现在刷新页面几乎就和刷新静态页面的效果完全相同。