http://blog.csdn.net/yerenyuan_pku/article/details/72871268

上文我们一起学习了如何使用Spring容器来管理Redis单机版和集群版实现,本文我们将一起学习如何在业务逻辑中添加缓存。 
我们首先应该明了一个道理,在业务逻辑中添加缓存的一个指导思想就是添加缓存不能影响正常业务逻辑。那么应该怎么添加缓存呢?我们可看看首页大广告的展示流程,如下图所示。 

从上面的流程图可知,我们应在调用服务层的服务查询首页内容时添加缓存,其实在首页中我们只实现了首页大广告的展示,说得更具体点应是在查询内容列表时添加缓存,添加缓存的步骤如下:

  1. 查询数据库之前先查询缓存。
  2. 查询到结果,直接响应结果。
  3. 查询不到结果,即缓存中没有,那么需要查询数据库。
  4. 把查询结果添加到缓存中。
  5. 返回结果。

我们理清了这个流程,那么接下来就考虑一个问题,具体地我们要向Redis里面保存什么东西,Redis里面存放的都是key-value形式的数据,但是里面的内容全部都是字符串,我们不可能把一个java对象放到Redis数据库里面,但有时又有可能要存一个java对象进去,那么这时候该怎么存呢?我们应该把java对象转换成json字符串,这时候就可以存进去了。OK,key应该用内容分类id作为key,我们当时查询内容信息的时候也是根据内容分类id去查的,那么这时候我们要把缓存放到Redis数据库中去,所以这个key也应该是内容分类id吧!value呢?我们之前是根据内容分类id查询到一个内容列表,很显然这个内容列表就是一个java对象,我们可以把它转成json,然后把它存到Redis里面去就可以了。 
key和value想明白了,那还有一个问题,我们这个缓存不可能只是为内容作缓存,有可能还会对商品、用户、…作缓存,这个时候key就会很多,用内容分类id作为key的话,有可能会重复,如果要是重复了,就会跟别的key冲突,要是发生冲突了,那么这个缓存数据就不对了。那么这时候怎么办?我们要防止key冲突,我们得对这个key进行归类,可以使用hash来对其进行归类。 
我们是以首页大广告位的展示为例,我们便给hkey(分类)起个名字,叫”CONTENT_KEY”,为了不把代码写死,我们把它放到配置文件当中,如下图所示。 

我们在taotao-content-service工程中添加了一个resource.properties文件,所以需要在Spring容器中扫描进去,我们把applicationContext-dao.xml文件中加载配置文件这一行做下修改,将db.properties修改为*.properties。这样properties目录下所有的以properties结尾的文件都会被加载进来。 

下面我们修改taotao-content-service工程下的ContentServiceImpl类中的getContentList方法,如下所示。

@Override
public List<TbContent> getContentList(long cid) {// 查询数据库之前,先查询缓存,并且添加缓存不能影响正常业务逻辑try {String json = jedisClient.hget(CONTENT_KEY, cid + ""); // 判断是否命中缓存,判断json字符串是否为null或"" if (StringUtils.isNotBlank(json)) { // 把这个json转换成List集合 List<TbContent> list = JsonUtils.jsonToList(json, TbContent.class); return list; } } catch (Exception e) { e.printStackTrace(); } // 根据内容分类id查询内容列表 TbContentExample example = new TbContentExample(); // 设置查询条件 Criteria criteria = example.createCriteria(); criteria.andCategoryIdEqualTo(cid); // 执行查询 List<TbContent> list = contentMapper.selectByExample(example); // 向缓存中保存结果,并且添加缓存不能影响正常业务逻辑 try { jedisClient.hset(CONTENT_KEY, cid + "", JsonUtils.objectToJson(list)); } catch (Exception e) { e.printStackTrace(); } return list; }

我们可以在以下代码处

String json = jedisClient.hget(CONTENT_KEY, cid + "");

打断点查看一下第一次访问首页大广告位和第二次访问首页大广告位的情况。 
缓存有个问题就是如果数据库表中的数据做了修改,缓存是需要同步的,否则查询的还是老数据,因此凡是涉及增、删、改的操作都需要同步缓存。我们以添加内容为例,应将ContentServiceImpl类中的insertContent方法修改为:

@Override
public TaotaoResult insertContent(TbContent content) {// 补全pojo的属性content.setCreated(new Date()); content.setUpdated(new Date()); // 向内容表中插入数据 contentMapper.insert(content); // 做缓存同步,清除redis中内容分类id对应的缓存信息 jedisClient.hdel(CONTENT_KEY, content.getCategoryId().toString()); return TaotaoResult.ok(); }

为方便大家复制,现将ContentServiceImpl类的代码贴出。

/*** 内容管理Service* <p>Title: ContentServiceImpl</p>* <p>Description: </p>* <p>Company: www.itcast.cn</p> * @version 1.0*/
@Service
public class ContentServiceImpl implements ContentService { @Autowired private TbContentMapper contentMapper; @Autowired private JedisClient jedisClient; @Value("${CONTENT_KEY}") private String CONTENT_KEY; @Override public TaotaoResult insertContent(TbContent content) { // 补全pojo的属性 content.setCreated(new Date()); content.setUpdated(new Date()); // 向内容表中插入数据 contentMapper.insert(content); // 做缓存同步,清除redis中内容分类id对应的缓存信息 jedisClient.hdel(CONTENT_KEY, content.getCategoryId().toString()); return TaotaoResult.ok(); } @Override public List<TbContent> getContentList(long cid) { // 查询数据库之前,先查询缓存,并且添加缓存不能影响正常业务逻辑 try { String json = jedisClient.hget(CONTENT_KEY, cid + ""); // 判断是否命中缓存,判断json字符串是否为null或"" if (StringUtils.isNotBlank(json)) { // 把这个json转换成List集合 List<TbContent> list = JsonUtils.jsonToList(json, TbContent.class); return list; } } catch (Exception e) { e.printStackTrace(); } // 根据内容分类id查询内容列表 TbContentExample example = new TbContentExample(); // 设置查询条件 Criteria criteria = example.createCriteria(); criteria.andCategoryIdEqualTo(cid); // 执行查询 List<TbContent> list = contentMapper.selectByExample(example); // 向缓存中保存结果,并且添加缓存不能影响正常业务逻辑 try { jedisClient.hset(CONTENT_KEY, cid + "", JsonUtils.objectToJson(list)); } catch (Exception e) { e.printStackTrace(); } return list; } }
  • 1

下面我们便来添加一条广告,那么会先清除缓存然后再去查询数据库。 

转载于:https://www.cnblogs.com/telwanggs/p/6961643.html

(转)淘淘商城系列——在业务逻辑中添加缓存相关推荐

  1. 学习淘淘商城第三十四课(在业务逻辑中添加缓存)

    上节课我们一起学习了如何用Spring容器来管理Redis单机版和集群版实现.这节我们来学习下在业务中添加缓存. Redis添加缓存有两种方式,一种是set,另一种是hset,这两种方式的不同之处是h ...

  2. xxljob在业务代码中添加任务(登录后token验证)

    之前做过一次在业务代码中调用xxljob的接口添加任务启动任务,xxljob的接口添加免登录验证注解后直接调用,博文地址:xxl-job 在业务代码中添加任务,后面用到的groupId获取方法也在这里 ...

  3. [沁恒单片机系列]一、Keil中添加沁恒单片机型号

    [沁恒单片机系列]一.Keil中添加沁恒单片机型号 1.前言 2.解决方法 1.前言 偶然了解到沁恒的CH552T带的USB单片机,价格非常美丽,性能也不错,主频高达24MHZ,官方提供的WCHSPT ...

  4. 【Lilishop商城】No4-2.业务逻辑的代码开发,涉及到:会员B端第三方登录的开发-平台注册会员接口开发

    仅涉及后端,全部目录看顶部专栏,代码.文档.接口路径在: [Lilishop商城]记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇会结合业务介绍重点设计逻辑,其中重点包括接口 ...

  5. 【Lilishop商城】No4-1.业务逻辑的代码开发,涉及到:会员B端第三方登录使用及后端接口(微信、QQ等)

    仅涉及后端,全部目录看顶部专栏,代码.文档.接口路径在: [Lilishop商城]记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇会结合业务介绍重点设计逻辑,其中重点包括接口 ...

  6. 【Lilishop商城】No4-6.业务逻辑的代码开发,涉及到:接口入参、出参开发逻辑,及POJO的各种总结

     仅涉及后端,全部目录看顶部专栏,代码.文档.接口路径在: [Lilishop商城]记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇会结合业务介绍重点设计逻辑,其中重点包括接 ...

  7. 如何优雅的处理业务逻辑中的定时和延时问题?

    本文将从如何处理业务流程和信息分发中的定时和延时问题出发,横向比较了业界常见的几种方案,如直接多线程编码.Spring定时调度框.大型分布式调度框架.消息中间件定时消息,因为消息中间件接口友好,调用方 ...

  8. Sharepoint学习笔记—Ribbon系列-- 2. 在Ribbon中添加新Tab

    有了上面的基础,我们来看看如何向Sharepoint网站的Ribbon中添加我们定义的Tab. 直接进入操作步骤 一.创建 SharePoint 项目 要添加新选项卡,应首先创建一个空白 ShareP ...

  9. 分销系统商城小程序业务逻辑功能设计_OctShop

    在移动互联网的不断发展壮大的形势下,用户和流量也在飞速的激增.小程序商城的体系也越来越成熟,很多小程序商城的营销方式也不断涌现.如:限时抢,拼团,优惠券等等,其中分销系统商城是受欢迎的,引起了高度关注 ...

最新文章

  1. 齐次坐标的理解(1)
  2. pat 乙级1033 旧键盘打字(20)
  3. Photoshop画笔的混合算法实现(逆推)
  4. HATEOAS的RESTful服务。 超媒体:REST的秘密要素
  5. Intel 64/x86_64/IA-32/x86处理器 - SIMD指令集 - SSE扩展(12) - 预取指令与SFENCE指令
  6. kali linux 网络命令,Kali Linux系统连接Wifi无线网络命令:
  7. 评论:我们该如何应对科技发展带来的失业
  8. 多通道卷积的参数数量计算
  9. 蓝桥杯-基础练习 十六进制转八进制
  10. python匹配部分字符串_python – 即使只是部分匹配字符串,如何匹配字符串?
  11. Android 存储学习之SQLite数据库的基本操作
  12. jxl java mer_导出报表出错,有没有大神懂得
  13. 检查服务器端口占用,服务器中如何检查端口是否开放
  14. navicat怎么清除干净
  15. 使用任意波形(或函数)发生器产生想要的任意信号
  16. linux pdf中文乱码,英文乱码(乱码为方格之类的解决方法)
  17. YAML简介(.yml文件后缀)
  18. 尝试使用sklearn自动进行多模型预测并计算权重
  19. 记录一次teamview无法远程连接对方teamview的过程
  20. 实验:跨域VPN-OptionC方式-方案二

热门文章

  1. matlab 排课代码,matlab遗传算法排课问题,程序一直有错,求解答
  2. (73)FPGA模块调用(VHDL调用system Verilog)
  3. 5004. boost 源码编译vs2019
  4. onenote快捷键_onenote链接系列:链接笔记如何产生?与插入链接的区别
  5. 【C语言】找到兼职了心情紧张!
  6. python算法应用(五)——搜索与排名1(连接数据库及简单排名)
  7. STM32学习——ADC采集
  8. Linux的capability深入分析(1)
  9. brew安装mysql 卸载_Mac卸载mysql并安装mysql升级到8.0.13版本
  10. how to reference the parent form from the WPF control(Control in ElementHost)