先奉上redis操做工具类html
package com.hz1202.miaosha.service; import com.alibaba.fastjson.JSON; import com.hz1202.miaosha.redis.KeyPrefix; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; /** * @Author: mol * @Description: * @Date: create in 13:19 2018/5/3 */ @Service public class RedisService { @Autowired JedisPool jedisPool; /** * redis get方法(该工具中为了保证全部key都惟一 因此给每个key都加了前缀) * @param prefix 前缀 * @param key key值 * @param clazz 获取后要转换成的对象类型 * @return 转换后的对象 */ public <T> T get(KeyPrefix prefix,String key, Class<T> clazz){ Jedis jedis = null; try { //获取jedis jedis = jedisPool.getResource(); //获取真正的key String realKey = prefix.getPrefix()+key; String str = jedis.get(realKey); //将获取到的String转换成clazz对象 T t = StringToBean(str,clazz); return t; }finally { //完成后回收资源 returnToPool(jedis); } } /** * redis set方法(该工具中为了保证全部key都惟一 因此给每个key都加了前缀) * @param prefix 前缀 * @param key key值 * @param value 要保存的数据 */ public <T> Boolean set(KeyPrefix prefix,String key,T value){ Jedis jedis = null; try { //获取jedis jedis = jedisPool.getResource(); //将对象转换为字符串 String str = beanToString(value); if(str == null || str.length() <= 0){ return false; } //生成真正的key String realKey = prefix.getPrefix()+key; //获取key有效时间 int seconds = prefix.expireSeconds(); //若是有效时间小于等于0,说名该key值永久有效,不然在保存数据时须要加入有效时间 if(seconds <= 0){ jedis.set(realKey,str); }else{ jedis.setex(realKey,seconds,str); } return true; }finally { returnToPool(jedis); } } /** * 判断key是否存在 * @param prefix 前缀 * @param key key值 * @return */ public Boolean exists(KeyPrefix prefix,String key){ Jedis jedis = null; try { jedis = jedisPool.getResource(); //生成真正的key String realKey = prefix.getPrefix()+key; jedis.exists(realKey); return true; }finally { returnToPool(jedis); } } /** * 给当前的key对应的value + 1 * @param prefix 前缀 * @param key key值 * @return */ public Boolean incr(KeyPrefix prefix,String key){ Jedis jedis = null; try { jedis = jedisPool.getResource(); //生成真正的key String realKey = prefix.getPrefix()+key; jedis.incr(realKey); return true; }finally { returnToPool(jedis); } } /** * 给当前key对应的value - 1 * @param prefix 前缀 * @param key key * @return */ public Boolean decr(KeyPrefix prefix,String key){ Jedis jedis = null; try { jedis = jedisPool.getResource(); //生成真正的key String realKey = prefix.getPrefix()+key; jedis.decr(realKey); return true; }finally { returnToPool(jedis); } } /** * 将对象转换为字符串 * @param value * @param <T> * @return */ private <T> String beanToString(T value) { if(value == null){ return null; } Class<?> clazz = value.getClass(); if(clazz == int.class || clazz == Integer.class){ return value+""; }else if(clazz == String.class){ return (String) value; }else if(clazz == Long.class || clazz == long.class){ return value+""; }else{ return JSON.toJSONString(value); } } /** * 将String 转换为对象 * @param str * @param clazz * @param <T> * @return */ @SuppressWarnings("unchecked") private <T> T StringToBean(String str,Class<T> clazz) { if(str == null || str.length() <= 0 || clazz == null){ return null; } if(clazz == int.class || clazz == Integer.class){ return (T)Integer.valueOf(str); }else if(clazz == String.class){ return (T)str; }else if(clazz == Long.class || clazz == long.class){ return (T)Long.valueOf(str); }else{ return JSON.toJavaObject(JSON.parseObject(str),clazz); } } /** * 回收redis资源 * @param jedis */ private void returnToPool(Jedis jedis) { if(jedis!=null){ jedis.close(); } } }
前缀和有效时间前端
package com.hz1202.miaosha.redis; /** * @Author: mol * @Description: * @Date: create in 14:46 2018/5/3 */ public abstract class BasePrefix implements KeyPrefix{ //有效时间 private int expireSeconds; //前缀 private String prefix; public BasePrefix(String prefix) { this.expireSeconds = 0; this.prefix = prefix; } public BasePrefix(int expireSeconds, String prefix) { this.expireSeconds = expireSeconds; this.prefix = prefix; } @Override public int expireSeconds() {//默认0表明永不过时 return expireSeconds; } @Override public String getPrefix() { String simpleName = getClass().getSimpleName(); return simpleName+":"+prefix; } }
package com.hz1202.miaosha.redis; /** * @Author: mol * @Description: * @Date: create in 14:44 2018/5/3 */ public interface KeyPrefix { int expireSeconds(); String getPrefix(); }
各个模块的前缀和有效时间均可以经过继承 BasePrefix 来控制java
例如商品模块redis
package com.hz1202.miaosha.redis; public class GoodsKey extends BasePrefix { private GoodsKey(String prefix,int expireSeconds) { super(expireSeconds,prefix); } //前缀为“gl”有效时间为“60”秒 public static GoodsKey getGoodsList =new GoodsKey("gl",60); //前缀为“gd”有效时间为“60”秒 public static GoodsKey getGoodsDetail =new GoodsKey("gd",60); }
正常状况下咱们可能经过如下代码进入商品列表页面spring
@RequestMapping(value = "/to_list") public String toListHtml(Model model){ List<GoodsVo> goodsVos = goodsService.listGoodsVo(); model.addAttribute("goodsList",goodsVos); return "goods_list"; }
在作页面缓存时,咱们直接将一个HTML代码返回给前端页面json
@RequestMapping(value = "/to_list",produces="text/html") @ResponseBody public String toListHtml(Model model, MiaoShaUser user, HttpServletRequest request, HttpServletResponse response){ //取缓存 String str = redisService.get(GoodsKey.getGoodsList, "", String.class); if(!StringUtils.isEmpty(str)){ return str; } //缓存中没有,咱们先获取商品信息 List<GoodsVo> goodsVos = goodsService.listGoodsVo(); model.addAttribute("goodsList",goodsVos); model.addAttribute("user",user); //而后进行手动渲染 SpringWebContext swc = new SpringWebContext(request,response,request.getServletContext(), request.getLocale(),model.asMap(),application); //goods_list 指的是前端页面模版(即你要将数据返回到哪一个页面) str = thymeleafViewResolver.getTemplateEngine().process("goods_list", swc); //存入redis if(!StringUtils.isEmpty(str)){ redisService.set(GoodsKey.getGoodsList,"",str); } return str; }
以上咱们看处处理页面缓存,只须要在原有的基础上作如下处理:缓存
一、在RequestMapping中加上 produces = "text/html",表示该方法将产生HTML代码数据app
二、先从redis中获取数据ide
三、若是redis中没有数据则经过业务逻辑获取相关的数据后进行手动渲染,生成HTML代码,而后存入redis,最后将生成的代码返回给模板工具