概述
根据数据的特点,不经常变动的数据 即时性要求没有那么高的读数据 为了减轻DB压力,我们可以将数据放到缓存中。
按照规划,目前我们需要将区域信息、商铺分类信息和头条信息放入到redis中。
实战SSM_O2O商铺_45【Redis缓存】配置Redis在Service层加入缓存中我们集成了Redis的配置,并使用AreaService来测试了配置的正确性。 接下来我们继续将商铺分类信息和头条信息放入到redis中。
HeadLineServiceImpl的改造
代码
思路:根据mapper中不同的查询条件,在service层缓存不同的KEY,方便使用。
package com.artisan.o2o.service.impl; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.artisan.o2o.cache.JedisUtil; import com.artisan.o2o.dao.HeadLineDao; import com.artisan.o2o.entity.HeadLine; import com.artisan.o2o.service.HeadLineService; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; @Service public class HeadLineServiceImpl implements HeadLineService { private static final Logger logger = LoggerFactory.getLogger(HeadLineServiceImpl.class); @Autowired HeadLineDao headLineDao; @Autowired private JedisUtil.Strings jedisStrings; @Autowired private JedisUtil.Keys jedisKeys; @Override public List<HeadLine> queryHeadLineList(HeadLine headLineConditon) { List<HeadLine> headLineList = new ArrayList<HeadLine>(); // 定义Key String key = "headline"; // 定义jackson数据转换操作类 ObjectMapper mapper = new ObjectMapper(); // 根据mapper中的查询条件 拼装key // 根据不同的条件缓存不同的key值 这里有3种缓存 headline_0 headline_1 和 headline 方便管理员权限操作 if (headLineConditon != null && headLineConditon.getEnableStatus() != null) { key = key + "_" + headLineConditon.getEnableStatus(); } // 如果不存在,从数据库中获取数据,然后写入redis if(!jedisKeys.exists(key)){ try { // 从DB中获取数据 headLineList = headLineDao.selectHeadLineList(headLineConditon); // 将相关的实体类集合转换成string,存入redis里面对应的key中 String jsonString = mapper.writeValueAsString(headLineList); jedisStrings.set(key, jsonString); } catch (JsonProcessingException e) { e.printStackTrace(); logger.error("实体类集合转换string存入redis异常{}", e.getMessage()); } catch (Exception e) { e.printStackTrace(); logger.error("其他异常{}", e.getMessage()); } } else { // 否则直接从redis中获取 try { // 若存在,则直接从redis里面取出相应数据 String jsonString = jedisStrings.get(key); // 指定要将string转换成的集合类型 JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class, HeadLine.class); // 将相关key对应的value里的的string转换成java对象的实体类集合 headLineList = mapper.readValue(jsonString, javaType); } catch (Exception e) { e.printStackTrace(); logger.error("异常{}", e.getMessage()); } } return headLineList; } }
单元测试
tb_head_line数据
package com.artisan.o2o.service; import java.util.List; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import com.artisan.o2o.BaseTest; import com.artisan.o2o.entity.HeadLine; public class HeadLineServiceTest extends BaseTest { @Autowired private HeadLineService headLineService; @Test public void testQueryHeadLineList() { HeadLine headLineConditon = new HeadLine(); // 状态 0 不可用 1 可用 headLineConditon.setEnableStatus(0); // 查询不可用的头条信息 List<HeadLine> headLineList = headLineService.queryHeadLineList(headLineConditon); for (HeadLine headLine : headLineList) { System.out.println("0<<<<" + headLine); } // 查询可用的头条信息 headLineConditon.setEnableStatus(1); headLineList = headLineService.queryHeadLineList(headLineConditon); for (HeadLine headLine : headLineList) { System.out.println("**------>" + headLine); } // 再次查询 状态为0 和 1的头条信息 ,确保从缓存中取数据 // 查询不可用的头条信息 headLineConditon.setEnableStatus(0); headLineList = headLineService.queryHeadLineList(headLineConditon); for (HeadLine headLine : headLineList) { System.out.println("0>>>>" + headLine); } // 查询可用的头条信息 headLineConditon.setEnableStatus(1); headLineList = headLineService.queryHeadLineList(headLineConditon); for (HeadLine headLine : headLineList) { System.out.println("||------>" + headLine); } } }
启动redis服务端,确保redis中无对应的数据,加入断点逐步调测观察。 单元测试后查看Redis中的数据
127.0.0.1:6379> get headline_0 "[]" 127.0.0.1:6379> get headline_1 "[{\"lineId\":6,\"lineName\":\"\xe8\xb4\xad\xe7\x89\xa9\",\"lineLink\":\"xxx\",\"lineImg\":\"\\\\upload\\\\item\\\\headtitle\\\\2018072520315746624.jpg\",\"priority\":99,\"enableStatus\":1,\"createTime\":null,\"lastEditTime\":null},{\"lineId\":2,\"lineName\":\"\xe5\xae\xb6\xe5\x85\xb7\",\"lineLink\":\"x\",\"lineImg\":\"\\\\upload\\\\item\\\\headtitle\\\\2018072520371786788.jpg\",\"priority\":98,\"enableStatus\":1,\"createTime\":null,\"lastEditTime\":null},{\"lineId\":3,\"lineName\":\"\xe5\x81\xa5\xe8\xba\xab\",\"lineLink\":\"xx\",\"lineImg\":\"\\\\upload\\\\item\\\\headtitle\\\\2018072520393452772.jpg\",\"priority\":97,\"enableStatus\":1,\"createTime\":null,\"lastEditTime\":null},{\"lineId\":4,\"lineName\":\"\xe7\xbe\x8e\xe5\xae\xb9\",\"lineLink\":\"aa\",\"lineImg\":\"\\\\upload\\\\item\\\\headtitle\\\\2018072520400198256.jpg\",\"priority\":96,\"enableStatus\":1,\"createTime\":null,\"lastEditTime\":null}]" 127.0.0.1:6379>
符合预期,测试通过。
ShopCategoryServiceImpl的改造
思路:根据mapper中不同的查询条件,在service层缓存不同的KEY,方便使用。
代码
package com.artisan.o2o.service.impl; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.artisan.o2o.cache.JedisUtil; import com.artisan.o2o.dao.ShopCategoryDao; import com.artisan.o2o.entity.ShopCategory; import com.artisan.o2o.service.ShopCategoryService; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; @Service public class ShopCategoryServiceImpl implements ShopCategoryService { private static final Logger logger = LoggerFactory.getLogger(ShopCategoryServiceImpl.class); @Autowired private ShopCategoryDao shopCategoryDao; @Autowired private JedisUtil.Keys jedisKeys; @Autowired private JedisUtil.Strings jedisStrings; @Override public List<ShopCategory> getShopCategoryList(ShopCategory shopCategory) { List<ShopCategory> shopCategoryList = new ArrayList<ShopCategory>(); // 定义redis中key String key = "shopcategory"; // 定义jackson数据转换操作类 ObjectMapper mapper = new ObjectMapper(); // 根据mapper中的查询条件,拼装shopcategory的key if (shopCategory == null) { // 查询条件为空,列出所有的首页大类,即parentId为空的店铺类别 key = key + "_allfirstlevelshopcategory"; } else if (shopCategory != null && shopCategory.getParent() != null && shopCategory.getParent().getShopCategoryId() != null) { // 列出某个parentId下面的所有子类 key = key + "_parent" + shopCategory.getParent().getShopCategoryId(); } else if (shopCategory != null) { // 列出所有的子类,不管属于哪个类 key = key + "_allsecondlevelshopcategory"; } // 如果缓存中不出在则从DB中查询并缓存到redis中 if (!jedisKeys.exists(key)) { try { // 从DB中加载 shopCategoryList = shopCategoryDao.queryShopCategoryList(shopCategory); // 将相关的实体类集合转换成string,存入redis里面对应的key中 String jsonString = mapper.writeValueAsString(shopCategoryList); jedisStrings.set(key, jsonString); } catch (JsonProcessingException e) { e.printStackTrace(); logger.error("实体类集合转换string存入redis异常{}", e.getMessage()); } catch (Exception e) { e.printStackTrace(); logger.error("其他异常{}", e.getMessage()); } } else { // 否则直接从redis中获取 try { String jsonString = jedisStrings.get(key); // 指定要将string转换成的集合类型 JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class, ShopCategory.class); // 将相关key对应的value里的的string转换成java对象的实体类集合 shopCategoryList = mapper.readValue(jsonString, javaType); } catch (Exception e) { e.printStackTrace(); logger.error("异常{}", e.getMessage()); } } return shopCategoryList; } }
单元测试
tb_shop_category 数据
package com.artisan.o2o.service; import java.util.List; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import com.artisan.o2o.BaseTest; import com.artisan.o2o.entity.ShopCategory; public class ShopServiceCategoryTest extends BaseTest { @Autowired ShopCategoryService shopCategoryService; @Test public void testQueryShopCategory() { List<ShopCategory> shopCategories; // 查询 ShopCategory为null的情况,即查询parent_id is null shopCategories = shopCategoryService.getShopCategoryList(null); for (ShopCategory shopCategory2 : shopCategories) { System.out.println("-----||" + shopCategory2); } // 查询 ShopCategory不为空的情况 ShopCategory shopCategory = new ShopCategory(); shopCategories = shopCategoryService.getShopCategoryList(shopCategory); for (ShopCategory shopCategory2 : shopCategories) { System.out.println("----->>" + shopCategory2); } // 查询对应父类下的目录 ShopCategory parent = new ShopCategory(); ShopCategory child = new ShopCategory(); parent.setShopCategoryId(1L); child.setParent(parent); shopCategories = shopCategoryService.getShopCategoryList(child); for (ShopCategory shopCategory2 : shopCategories) { System.out.println("-----**" + shopCategory2); } } }
运行两次,查看数据,符合预期