先奉上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,最後將生成的代碼返回給模板工具