淘淘商城第79讲——商品详情页面展示时添加缓存

上文我们一起分析了下如何在商品详情页面展示时添加缓存,本文我会带领大家一起实现商品详情页面展示时缓存的添加。

首先,我们要想清楚缓存应该加到哪个工程当中,目前我们有两个工程可以选择,第一个工程是taotao-item-web(商品详情展示工程),如果把缓存加到这个工程的话,由于该工程是个web工程,不被其它工程所共用,那么这块缓存的功能就只能被它自己使用。第二个工程是taotao-manager(商品服务工程),由于多个工程都可以依赖taotao-manager,因此缓存的功能可以被多个工程所共用。很显然,我们应该选择第二个工程来添加缓存,即在taotao-manager工程中添加缓存。还有,要使用到Redis缓存技术,因此还须在该工程中添加对Redis的依赖,如下图所示。
在这里插入图片描述
添加完依赖之后,taotao-manager-service工程中还需要添加对Redis操作的接口及实现类,由于咱们在taotao-content-service工程中已经写过了,因此我们只需要把该工程中关于jedis接口的包、接口及其实现类都拷贝过来,并将包名由原来的com.taotao.content.jedis改为ccom.taotao.manager.jedis,如下图所示。
在这里插入图片描述
然后,咱们还需要把taotao-conent-service工程中的applicationContext-redis.xml配置文件给复制过来,如下图所示。
在这里插入图片描述
打开以上配置文件,如下图所示,可以看到有单机版和集群版两种配置,但我目前使用的是单机版的Redis配置。
在这里插入图片描述
在上文中我们制定了通过添加Redis缓存前缀来区分key的策略,而且这个前缀我们又不能写死到代码当中,所以我们最好将其设置到配置文件当中,还有就是商品的过期时间,这个也应该是要进行配置的,因此我们需要在taotao-manager-service工程中添加一个如下resource.properties配置文件,如下图所示。
在这里插入图片描述
其中,resource.properties配置文件中的内容如下所示:

# Redis中缓存商品信息的前缀
ITEM_INFO_KEY=ITEM_INFO
# 设置商品数据缓存的过期时间,默认为1天
ITEM_INFO_KEY_EXPIRE=86400

添加好了以上配置文件之后,那么就要让Spring容器能够扫描到它,因此在applicationContext-dao.xml配置文件中我们要确保properties目录下的所有配置文件都可以被扫描到。
在这里插入图片描述
接着,我们开始要真正编写有关添加缓存的代码了,在ItemServiceImpl类中的获取商品基本信息方法(getItemById)和获取商品描述信息方法(getItemDescById)中添加缓存代码,添加完缓存后,该类的完整代码如下所示。

package com.taotao.service.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taotao.common.pojo.EasyUIDataGridResult;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.common.utils.IDUtils;
import com.taotao.common.utils.JsonUtils;
import com.taotao.manager.jedis.JedisClient;
import com.taotao.mapper.TbItemDescMapper;
import com.taotao.mapper.TbItemMapper;
import com.taotao.pojo.TbItem;
import com.taotao.pojo.TbItemDesc;
import com.taotao.pojo.TbItemExample;
import com.taotao.service.ItemService;

@Service
public class ItemServiceImpl implements ItemService {
	
	@Autowired
	private TbItemMapper tbItemMapper;

	@Autowired
	private TbItemDescMapper itemDescMapper;
	
	@Autowired
	private JmsTemplate jmsTemplate;
	
	@Resource(name="topicDestination")
	private Destination destination;
	
	@Autowired
	private JedisClient client;
	
	@Value("${ITEM_INFO_KEY}")
	private String ITEM_INFO_KEY;
	
	@Value("${ITEM_INFO_KEY_EXPIRE}")
	private Integer ITEM_INFO_KEY_EXPIRE;
	
	
	@Override
	public TbItem getItemById(Long itemId) {
		// 添加缓存,有一个原则,即不能影响正常的业务逻辑
		
		// 1. 从缓存中获取数据,如果有就直接返回
		try {
			String jsonstr = client.get(ITEM_INFO_KEY + ":" + itemId + ":BASE");
			if (StringUtils.isNotBlank(jsonstr)) {
				// 还得重新设置商品的有效期
				client.expire(ITEM_INFO_KEY + ":" + itemId + ":BASE", ITEM_INFO_KEY_EXPIRE); // 设置缓存的有效期为一天
				return JsonUtils.jsonToPojo(jsonstr, TbItem.class);
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		
		// 2. 如果没有数据,就从数据库中查询
		// 注入Mapper
		// 调用方法
		TbItem item = tbItemMapper.selectByPrimaryKey(itemId);
		// 返回TbItem对象
		
		// 3. 添加缓存到Redis数据库中
		try {
			// 注入JedisClient
			client.set(ITEM_INFO_KEY + ":" + itemId + ":BASE", JsonUtils.objectToJson(item));
			// 设置缓存的有效期,以提供我们缓存的利用率
			client.expire(ITEM_INFO_KEY + ":" + itemId + ":BASE", ITEM_INFO_KEY_EXPIRE); // 设置缓存的有效期为一天
		} catch (Exception e) {
			e.printStackTrace();
		}
		return item;
	}

	@Override
	public EasyUIDataGridResult getItemList(Integer page, Integer rows) {
		// 1. 设置分页的信息,使用PageHelper
		if (page == null) {
			page = 1;
		}
		if (rows == null) {
			rows = 30;
		}
		PageHelper.startPage(page, rows);
		// 2. 注入Mapper
		// 3. 创建一个TbItemExample对象,而且不需要设置查询条件
		TbItemExample example = new TbItemExample();
		// 4. 根据Mapper调用查询所有数据的方法
		List<TbItem> list = tbItemMapper.selectByExample(example);
		// 5. 获取分页信息
		PageInfo<TbItem> info = new PageInfo<TbItem>(list);
		// 6. 封装到EasyUIDataGridResult对象中并返回
		EasyUIDataGridResult result = new EasyUIDataGridResult();
		result.setTotal((int)info.getTotal());
		result.setRows(info.getList());
		return result;
	}

	@Override
	public TaotaoResult addItem(TbItem item, String desc) {
		// 生成商品id
		long itemId = IDUtils.genItemId();
		// 补全item对象的属性
		item.setId(itemId);
		// 商品状态,1:正常,2:下架,3:删除
		item.setStatus((byte) 1);
		item.setCreated(new Date());
		item.setUpdated(new Date());
		// 向商品表中插入数据
		tbItemMapper.insert(item);
		// 创建一个商品描述表对应的pojo
		TbItemDesc itemDesc = new TbItemDesc();
		// 补全pojo的属性
		itemDesc.setItemId(itemId);
		itemDesc.setItemDesc(desc);
		itemDesc.setCreated(new Date());
		itemDesc.setUpdated(new Date());
		// 向商品描述表中插入数据
		itemDescMapper.insert(itemDesc);
		
		// 添加一个发送消息的业务逻辑
		jmsTemplate.send(destination, new MessageCreator() {
			
			@Override
			public Message createMessage(Session session) throws JMSException {
				// 发送消息,发送的消息的内容就是商品id
				return session.createTextMessage(itemId + "");
			}
		});
		
		// 返回结果
		return TaotaoResult.ok();
	}

	@Override
	public TbItemDesc getItemDescById(Long itemId) {
		// 添加缓存,有一个原则,即不能影响正常的业务逻辑
		
		// 1. 从缓存中获取数据,如果有就直接返回
		try {
			String jsonstr = client.get(ITEM_INFO_KEY + ":" + itemId + ":DESC");
			if (StringUtils.isNotBlank(jsonstr)) {
				// 还得重新设置商品的有效期
				System.out.println("有缓存");
				client.expire(ITEM_INFO_KEY + ":" + itemId + ":DESC", ITEM_INFO_KEY_EXPIRE); // 设置缓存的有效期为一天
				return JsonUtils.jsonToPojo(jsonstr, TbItemDesc.class);
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		
		// 2.如果没有查到数据,则从数据库中查询
		TbItemDesc itemDesc = itemDescMapper.selectByPrimaryKey(itemId);
		
		// 3. 添加缓存到Redis数据库中
		try {
			// 注入JedisClient
			client.set(ITEM_INFO_KEY + ":" + itemId + ":DESC", JsonUtils.objectToJson(itemDesc));
			// 设置缓存的有效期,以提供我们缓存的利用率
			client.expire(ITEM_INFO_KEY + ":" + itemId + ":DESC", ITEM_INFO_KEY_EXPIRE); // 设置缓存的有效期为一天
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return itemDesc;
	}

}

其中新注入的内容用如下图所示的红色大框框标注出来了。
在这里插入图片描述
代码写好了之后,最后我们便要进行测试了,重启taotao-manager这个工程,重启成功后,我们再来访问商品详情页面,第一次访问是查询数据库,然后我们再刷新页面,第二次访问就是查询的缓存了,缓存中存储的商品基本信息如下图所示。
在这里插入图片描述
存储的商品描述信息如下图所示。
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李阿昀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值