1. 程式人生 > >淘淘商城25_商品詳情頁面實現02_商品詳情

淘淘商城25_商品詳情頁面實現02_商品詳情

一、展示商品詳情

1. dao層

2. Service層

3. serviceImpl

/**
	 * 查詢商品詳情
	 * @param itemId
	 * @return
	 */
	@Override
	public TbItemDesc getItemDescByItemId(long itemId) {
		TbItemDesc itemDesc = itemDescMapper.getTbItemDescByItemId(itemId);
		return itemDesc;
	}

4. Controller

/**
	 * 獲取商品的詳情
	 * 此處的引數來源是taotao-search-web下面的search.jsp頁面
	 * @param itemId
	 * @return
	 */
	@RequestMapping("/item/desc/{itemId}")
	@ResponseBody
	public String getItemDescByItemId(@PathVariable long itemId){
		TbItemDesc itemDesc = itemService.getItemDescByItemId(itemId);
		String desc = itemDesc.getItemDesc();//獲取商品的詳情
		return desc;
	}

二、展示規格引數

直接在Controller層裡,使用httpclient呼叫taotao-manager-service裡這個方法

http://localhost:8081/item/param/itemParamItems/{itemid}

/**
	 * 展示商品規格引數
	 * 直接用HttpClientUtil這個工具類呼叫taotao-manager-web
	 * @param itemId
	 * @return
	 */
	@RequestMapping("/item/param/{itemId}")
	@ResponseBody
	public String getItemParamByItemId(@PathVariable long itemId){
		String param = HttpClientUtil.doGet("http://localhost:8081/item/param/itemParamItems/"+itemId);
		return param;
	}

測試:出現亂碼

解決亂碼問題:在ItemParamController.java中修改

@RequestMapping(value="/itemParamItems/{itemId}", produces=MediaType.APPLICATION_JSON_VALUE+"; charset=utf-8;")

三、新增快取邏輯

1.需求分析

  1. 從solr庫查詢出的商品(減輕資料庫的壓力)
  2. 檢視商品的詳情,基本資訊,和商品描述,....放到redis快取裡,減輕資料庫的壓力
  3. 問題: 只要有使用者查詢完某一件商品,redis庫中就會儲存這個商品的資訊,(熱點資料),非熱點資料,
  4. 比如:7月份,搜尋羽絨服,  把羽絨服資訊儲存到redis庫中, 一直佔用redis快取,浪費硬碟空間,
  5. 生命週期,   可以給這個快取設定一個生命週期,  24小時

2. 新增快取邏輯

Redis的hash型別中的key是不能設定過期時間。如果還需要對key進行分類可以使用折中的方案。

Key的命名方式:

cctv:javaee16:01=李剛       cctv:javaee16:02=張三  

cctv:javaee17:01=張龍       cctv:javaee17:02=張飛

 

3. 配置檔案

3.1 在taotao-manager-service

3.2 將taotao-content-service中的applicationContext-jedis.xml複製到在taotao-manager-service中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
	http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
	
	     <!-- 連線池配置 可以不加-->
	    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
			<!-- 最大連線數 -->
			<property name="maxTotal" value="30" />
			<!-- 最大空閒連線數 -->
			<property name="maxIdle" value="10" />
			<!-- 每次釋放連線的最大數目 -->
			<property name="numTestsPerEvictionRun" value="1024" />
			<!-- 釋放連線的掃描間隔(毫秒) -->
			<property name="timeBetweenEvictionRunsMillis" value="30000" />
			<!-- 連線最小空閒時間 -->
			<property name="minEvictableIdleTimeMillis" value="1800000" />
			<!-- 連線空閒多久後釋放, 當空閒時間>該值 且 空閒連線>最大空閒連線數 時直接釋放 -->
			<property name="softMinEvictableIdleTimeMillis" value="10000" />
			<!-- 獲取連線時的最大等待毫秒數,小於零:阻塞不確定的時間,預設-1 -->
			<property name="maxWaitMillis" value="1500" />
			<!-- 在獲取連線的時候檢查有效性, 預設false -->
			<property name="testOnBorrow" value="true" />
			<!-- 在空閒時檢查有效性, 預設false -->
			<property name="testWhileIdle" value="true" />
			<!-- 連線耗盡時是否阻塞, false報異常,ture阻塞直到超時, 預設true -->
			<property name="blockWhenExhausted" value="false" />
		</bean>
		
		 <!-- 單機版jedis配置 -->
		<bean id="redisClient" class="redis.clients.jedis.JedisPool">
			<constructor-arg name="host" value="192.168.1.105"></constructor-arg>
			<constructor-arg name="port" value="6379"></constructor-arg>
	        <constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg>
		</bean>
		
		<bean id="jedisClient" class="com.taotao.dao.impl.JedisClientSingle"/>
</beans>

3.3 將taotao-content-service中的dao和daoImpl複製到在taotao-manager-service中

JedisClient.java

package com.taotao.dao;

public interface JedisClient {
	//set方法
	public String set(String key, String value);
	//get方法
	public String get(String key);
	//刪除key      del
	public long del(String key);
	//hset方法
	public long hset(String hkey, String key, String value);
	//hget方法
	public String hget(String hkey, String key);
	//刪除Hashkey    hdel
	public long hdel(String hkey, String key);
	//生命週期
	public long expire(String key, int second);
	//查詢剩餘生命週期
	public long ttl(String key);
	//自增
	public long incr(String key);
}

JedisClientSingle.java

package com.taotao.dao.impl;

import org.springframework.beans.factory.annotation.Autowired;

import com.taotao.dao.JedisClient;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class JedisClientSingle implements JedisClient {

	@Autowired
	private JedisPool jedisPool;
	
	/**
	 * set
	 */
	@Override
	public String set(String key, String value) {
		Jedis jedis = jedisPool.getResource();
		String str = jedis.set(key, value);
		jedis.close();
		return str;
	}

	/**
	 * get
	 */
	@Override
	public String get(String key) {
		Jedis jedis = jedisPool.getResource();
		String str = jedis.get(key);
		jedis.close();
		return str;
	}

	/**
	 * hash
	 * hset
	 */
	@Override
	public long hset(String hkey, String key, String value) {
		Jedis jedis = jedisPool.getResource();
		Long ss = jedis.hset(hkey, key, value);
		jedis.close();
		return ss;
	}

	/**
	 * hash  hget
	 */
	@Override
	public String hget(String hkey, String key) {
		Jedis jedis = jedisPool.getResource();
	   String str = jedis.hget(hkey, key);
	   jedis.close();
		return str;
	}

	/**
	 * expire
	 */
	@Override
	public long expire(String key, int second) {
		Jedis jedis = jedisPool.getResource();
		Long ss = jedis.expire(key, second);
		jedis.close();
		return ss;
	}

	/**
	 * ttl
	 */
	@Override
	public long ttl(String key) {
		Jedis jedis = jedisPool.getResource();
		Long ss = jedis.ttl(key);
		jedis.close();
		return ss;
	}

	/**
	 * incr
	 */
	@Override
	public long incr(String key) {
		Jedis jedis = jedisPool.getResource();
		Long ss = jedis.incr(key);
		jedis.close();
		return ss;
	}

	/**
	 * 刪除key
	 */
	@Override
	public long del(String key) {
		Jedis jedis = jedisPool.getResource();
		Long ss = jedis.del(key);
		jedis.close();
		return ss;
	}

	/**
	 * 刪除hashkey
	 */
	@Override
	public long hdel(String hkey, String key) {
		Jedis jedis = jedisPool.getResource();
		Long ss = jedis.hdel(hkey, key);
		jedis.close();
		return ss;
	}

}

3.4.  新增快取邏輯,定義一個配置檔案resource.properties

商品key的定義:

基本資訊:

REDIS_ITEM_KEY:商品id:base=json

描述:

REDIS_ITEM_KEY:商品id:desc=json

規格引數:

REDIS_ITEM_KEY:商品id:param=json

#商品資訊在redis中儲存的key

REDIS_ITEM_KEY=REDIS_ITEM_KEY

#商品資訊在快取中的過期時間   60*60*24(60秒*60分鐘*24小時)

REDIS_ITEM_EXPIRE=86400

3.5 修改applicationContext-dao.xml

4、程式碼的編寫

4.1. 查詢單個商品資訊   ItemServiceImpl.java

@Autowired
	private JedisClient jedisClient;
	
	@Value("${REDIS_ITEM_KEY}")
	private String REDIS_ITEM_KEY;//商品key值
	@Value("${REDIS_ITEM_EXPIRE}")
	public Integer REDIS_ITEM_EXPIRE;//生命週期
/**
	 * 根據商品id查詢商品
	 */
	@Override
	public TbItem getItemById(long itemId) {
		//3.從快取中獲取資料,若快取中有資料,則取,若無資料,則執行1、2的步驟
		String jedis = jedisClient.get(REDIS_ITEM_KEY+":"+itemId+": base");
		if (StringUtils.isNotEmpty(jedis)) {
			TbItem tbitem = JsonUtils.jsonToPojo(jedis, TbItem.class);
			return tbitem;
		}
		TbItem item = itemMapper.getItemById(itemId);
		//1.把查詢到的資料放入到快取中
		jedisClient.set(REDIS_ITEM_KEY+":"+itemId+": base", JsonUtils.objectToJson(item));
		//2.設定生命週期
		jedisClient.expire(REDIS_ITEM_KEY+":"+itemId+": base", REDIS_ITEM_EXPIRE);
		return item;
	}

4.2 查詢商品詳情

/**
	 * 查詢商品詳情
	 * @param itemId
	 * @return
	 */
	@Override
	public TbItemDesc getItemDescByItemId(long itemId) {
		//3.從快取中獲取資料,若快取中有資料,則取,若無資料,則執行1、2的步驟
		String jedis = jedisClient.get(REDIS_ITEM_KEY+":"+itemId+": base");
		if (StringUtils.isNotEmpty(jedis)) {
			TbItemDesc tbitem = JsonUtils.jsonToPojo(jedis, TbItemDesc.class);
			return tbitem;
		}
		TbItemDesc itemDesc = itemDescMapper.getTbItemDescByItemId(itemId);
		//1.把查詢到的資料放入到快取中
		jedisClient.set(REDIS_ITEM_KEY+":"+itemId+": base", JsonUtils.objectToJson(itemDesc));
		//2.設定生命週期
		jedisClient.expire(REDIS_ITEM_KEY+":"+itemId+": base", REDIS_ITEM_EXPIRE);
		return itemDesc;
	}