1. 程式人生 > >學習yijun zhang 老師的商品秒殺專案所得(1)——使用Redis做快取優化的簡單實現

學習yijun zhang 老師的商品秒殺專案所得(1)——使用Redis做快取優化的簡單實現

主要使用的功能: 1.基於java的redis工具——Jedis 2.JDK本身提供的序列化方式——實現Serializable 3.實現序列化要用到的IO流——ByteArrayInputStream,ByteArrayOutputStream,ObjectInputStream,ObjectOutputStream 實現: 1.JavaBean——Seckill.java

import java.io.Serializable;
import java.util.Date;
//秒殺商品的實體類
public class Seckill implements Serializable{
	/**
	 * serilVersionUID  表示該序列化的版本,反序列化的時候,JVM會將傳過來的位元組流中的serilVersionUID和對應實體類中的進行比較,如果相同,則成功,不同,則失敗
	 */
	private static final long serialVersionUID = 1L;
	
	private long seckillId;
	private String name;
	private int number;
	private Date startTime;
	private Date endTime;
	private Date createTime;
	public long getSeckillId() {
		return seckillId;
	}
	public void setSeckillId(long seckillId) {
		this.seckillId = seckillId;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getNumber() {
		return number;
	}
	public void setNumber(int number) {
		this.number = number;
	}
	public Date getStartTime() {
		return startTime;
	}
	public void setStartTime(Date startTime) {
		this.startTime = startTime;
	}
	public Date getEndTime() {
		return endTime;
	}
	public void setEndTime(Date endTime) {
		this.endTime = endTime;
	}
	public Date getCreateTime() {
		return createTime;
	}
	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}
	@Override
	public String toString() {
		return "Seckill [seckillId=" + seckillId + ", name=" + name + ", number=" + number + ", startTime=" + startTime
				+ ", endTime=" + endTime + ", createTime=" + createTime + "]";
	}
	
}

2.使用Redis——RedisCache.java

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import com.seckill.entity.Seckill;

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

/**
 * 包含存取兩個方法,以二進位制的形式將物件進行存取
 * @author Administrator
 *
 */
public class RedisCache {
	private JedisPool jedisPool;
	//初始化jedispool物件
	public  RedisCache(String ip, int port) {
		jedisPool = new JedisPool(ip, port);
	}
	//通過id來獲取快取的seckill物件
	public Seckill getSeckill(Long id) {
	//通過JedisPool提供的getResoure()方法來獲取jedis例項
		Jedis jedis = jedisPool.getResource();
		
		//給定key來查詢value並進行反序列化
		try {
			String key = "seckill" + id;
			//反序列化的關鍵程式碼
			byte[] bytes = jedis.get(key.getBytes());
			if(bytes != null) {
				ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
				ObjectInputStream os = new ObjectInputStream(bis);
				Seckill seckill = (Seckill)os.readObject();
				return seckill;
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}
	
	//通過序列化來將傳入的物件儲存在redis中
	//使用了ByteArrayOutputStream 和ObjectOutputStream,前者作用是獲取物件序列化後的二進位制陣列
	public String putSeckill(Seckill seckill) {
		try {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(bos);
			oos.writeObject(seckill);
			byte[] bytes = bos.toByteArray();
			if(bytes != null) {
				Jedis jedis = jedisPool.getResource();
				String i = jedis.set(("seckill"+seckill.getSeckillId()).getBytes(), bytes);
				return i;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}

3.Test類——SeckillDaoTest.java

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

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.seckill.dao.cache.RedisCache;
import com.seckill.entity.Seckill;

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration({"classpath:spring/spring-dao.xml"})
public class SeckillDaoTest {
	
	//對SeckillDao進行注入
	@Autowired
	private SeckillDao seckillDao;
	
	@Autowired
	private RedisCache redisDao;
	
	@Test
	public void testGetSeckillByRedis() {
		Long seckillId = 1001L;
		//從redis中獲取該物件,如果沒有就從資料庫中獲取並且存入redis
		Seckill seckill = redisDao.getSeckill(seckillId);
		//如果快取中沒有就從資料庫中獲取
		if(seckill == null) {
			seckill = seckillDao.queryById(seckillId);
		}
		redisDao.putSeckill(seckill);
		Seckill seckill1 = redisDao.getSeckill(seckillId);
		System.out.println(seckill1);
	}
	}

4.spring-dao.xml

        <!-- redisDao的bean配置 -->
        <bean id="reidsDao" class="com.seckill.dao.cache.RedisCache">
        	<constructor-arg index="0" value="localhost"/>
        	<constructor-arg index="1" value="6379"/>
        </bean>

這部分程式碼使用了redis儲存顯示的列表,代替頻繁的資料庫查詢操作,以提高效能。

第一次寫,只當是個人總結。如有錯誤,請各位儘快指正。