SpringBoot秒殺系統實戰06-安裝與集成redis

文章目錄

1.Redis 安裝

Window 下安裝
下載地址:https://github.com/MSOpenTech/redis/releases
Redis 支持 32 位和 64 位。這個需要根據你係統平臺的實際情況選擇,這裏我們下載 Redis-x64-xxx.zip壓縮包到 C 盤,解壓後,將文件夾重新命名爲 redis。

Windows環境安裝redis途中遇到的問題:
https://www.cnblogs.com/javabg/p/9133206.html

2.集成Redis

Jedis :jedis就是集成了redis的一些命令操作,封裝了redis的java客戶端。提供了連接池管理。一般不直接使用jedis,而是在其上在封裝一層,作爲業務的使用。

  • 添加Jedis依賴
 <dependency>
    	<groupId>redis.clients</groupId>
    	<artifactId>jedis</artifactId>
    	<version>2.7.3</version>
 </dependency>
  • 添加Fastjson依賴
<dependency>
    	<groupId>com.alibaba</groupId>
    	<artifactId>fastjson</artifactId>
    	<version>1.2.38</version>
</dependency>
  • 添加redis的配置項
redis.host=127.0.0.1
redis.port=6379
redis.timeout=10
redis.password=123456
redis.poolMaxTotal=1000
redis.poolMaxldle=500
redis.poolMaxWait=500
  • 新建一個包redis,在裏面新建一個RedisConfig類。
	@Component
	@ConfigurationProperties(prefix="redis")//將application.properties裏面前綴redis都讀取
	public class RedisConfig {
	private String host;
	private int port;
	private int timeout;
	private String password;
	private int poolMaxTotal;
	private int poolMaxldle;
	private int poolMaxWait;
	public String getHost() {
		return host;
	}
	public void setHost(String host) {
		this.host = host;
	}
	public int getPort() {
		return port;
	}
	public void setPort(int port) {
		this.port = port;
	}
	public int getTimeout() {
		return timeout;
	}
	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public int getPoolMaxTotal() {
		return poolMaxTotal;
	}
	public void setPoolMaxTotal(int poolMaxTotal) {
		this.poolMaxTotal = poolMaxTotal;
	}
	public int getPoolMaxldle() {
		return poolMaxldle;
	}
	public void setPoolMaxldle(int poolMaxldle) {
		this.poolMaxldle = poolMaxldle;
	}
	public int getPoolMaxWait() {
		return poolMaxWait;
	}
	public void setPoolMaxWait(int poolMaxWait) {
		this.poolMaxWait = poolMaxWait;
	}
}

注意:@ConfigurationProperties(prefix=“redis”)指定配置文件裏面前綴爲”redis”的配置項,與配置項裏面的屬性對應起來。

  • 再在redis包中創建RedisPoolFactory類,RedisPoolFactory 通過配置文件,生成Jedis連接池(配置),方便在RedisService中調用。
	@Service
	public class RedisPoolFactory {
	@Autowired
	RedisConfig redisConfig;
	//JedisPool的實例注入到spring容器裏面
		@Bean
		public JedisPool JedisPoolFactory() {
			JedisPoolConfig poolConfig=new JedisPoolConfig();
			System.out.println("redisConfig.getPoolMaxldle():"+redisConfig.getPoolMaxldle());
			System.out.println("redisConfig.getPoolMaxTotal():"+redisConfig.getPoolMaxTotal());
			System.out.println("redisConfig.getPoolMaxWait():"+redisConfig.getPoolMaxWait());
			System.out.println("redisConfig.getPassword():"+redisConfig.getPassword());
			poolConfig.setMaxIdle(redisConfig.getPoolMaxldle());
			poolConfig.setMaxTotal(redisConfig.getPoolMaxTotal());
			poolConfig.setMaxWaitMillis(redisConfig.getPoolMaxWait()*1000);//s-->ms
			//因爲我們使用的是s(秒)來配置的,而源碼使用的是ms(毫秒),所以轉換一下
			JedisPool jp=new JedisPool(poolConfig,redisConfig.getHost(),redisConfig.getPort(),
					redisConfig.getTimeout()*1000,redisConfig.getPassword(),0);
			return jp;
			
		}
}

注意:RedisPoolFactory 通過配置文件,生成Jedis連接池(配置),方便在RedisService中調用。

  • 再在redis包中創建RedisService類來提供所有關於redis的服務方法。
	@Service
	public class RedisService {
	@Autowired
	JedisPool jedisPool;	//會出現循環依賴---Circular reference  
	//RedisService引用JedisPool--JedisPool在RedisService,只有創建RedisService的實例纔可以獲取JedisPool的bean
	//所以需要單獨拿出JedisPool的bean
	/**
	 * 獲取單個對象
	 * @param prefix
	 * @param key
	 * @param data
	 * @return
	 */
	public <T> T get(KeyPrefix prefix,String key,Class<T> data){
		System.out.println("@RedisService-REDIES-GET!");
		Jedis jedis=null;
		//在JedisPool裏面取得Jedis
		try {
			jedis=jedisPool.getResource();
			//生成真正的key  className+":"+prefix;  BasePrefix:id1
			String realKey=prefix.getPrefix()+key;
			System.out.println("@RedisService-get-realKey:"+realKey);
			//System.out.println("jedis:"+jedis);
			String sval=jedis.get(realKey);
			System.out.println("@RedisService-getvalue:"+sval);
			//將String轉換爲Bean入後傳出
			T t=stringToBean(sval,data);
			return t;
		}finally {
			returnToPool(jedis);
		}
	}
	
	/**
	 * 移除對象,刪除
	 * @param prefix
	 * @param key
	 * @return
	 */
	public boolean delete(KeyPrefix prefix,String key){
		Jedis jedis=null;
		try {
			jedis=jedisPool.getResource();
			String realKey=prefix.getPrefix()+key;
			long ret=jedis.del(realKey);
			return ret>0;//刪除成功,返回大於0
			//return jedis.decr(realKey);
		}finally {
			returnToPool(jedis);
		}
	}
	
	/**
	 * 設置單個、多個對象
	 * @param prefix
	 * @param key
	 * @param value
	 * @return
	 */						//MiaoshaUserKey.token, token, user
	public <T> boolean set(KeyPrefix prefix,String key,T value){
		System.out.println("@RedisService-REDIES-SET!");
		Jedis jedis=null;
		try {//在JedisPool裏面取得Jedis
			jedis=jedisPool.getResource();
			String realKey=prefix.getPrefix()+key;
			System.out.println("@RedisService-key:"+key);
			System.out.println("@RedisService-getPrefix:"+prefix.getPrefix());
			//System.out.println("set-realKey:"+realKey);
			String s=beanToString(value);//將T類型轉換爲String類型,json類型??
			//System.out.println("s:"+s);
			if(s==null||s.length()<=0) {
				return false;
			}
			int seconds=prefix.expireSeconds();
			if(seconds<=0) {//有效期:代表不過期,這樣纔去設置
				jedis.set(realKey, s);
				//System.out.println("1");
			}else {//沒有設置過期時間,即沒有設置有效期,那麼自己設置。
				jedis.setex(realKey, seconds,s);
				//System.out.println("2");
			}
			return true;
		}finally {
			returnToPool(jedis);
			//System.out.println("3");
		}
	}
	/**
	 * 減少值
	 * @param prefix
	 * @param key
	 * @return
	 */
	public <T> Long decr(KeyPrefix prefix,String key){
		Jedis jedis=null;
		try {
			jedis=jedisPool.getResource();
			String realKey=prefix.getPrefix()+key;
			return jedis.decr(realKey);
		}finally {
			returnToPool(jedis);
		}
	}
	/**
	 * 增加值
	 * @param prefix
	 * @param key
	 * @return
	 */
	public <T> Long incr(KeyPrefix prefix,String key){
		Jedis jedis=null;
		try {
			jedis=jedisPool.getResource();
			String realKey=prefix.getPrefix()+key;
			return jedis.incr(realKey);
		}finally {
			returnToPool(jedis);
		}
	}	
	/**
	 * 檢查key是否存在
	 * @param prefix
	 * @param key
	 * @return
	 */
	public <T> boolean exitsKey(KeyPrefix prefix,String key){
		Jedis jedis=null;
		try {
			jedis=jedisPool.getResource();
			String realKey=prefix.getPrefix()+key;
			return jedis.exists(realKey);
		}finally {
			returnToPool(jedis);
		}
	}	
	/**
	 * 將字符串轉換爲Bean對象
	 * 
	 * parseInt()返回的是基本類型int 而valueOf()返回的是包裝類Integer  
	 * Integer是可以使用對象方法的  而int類型就不能和Object類型進行互相轉換 。
	 * int a=Integer.parseInt(s);
	   Integer b=Integer.valueOf(s);
	 */
	public static <T> T stringToBean(String s,Class<T> clazz) {
		if(s==null||s.length()==0||clazz==null) {
			return null;
		}		
		if(clazz==int.class||clazz==Integer.class) {
			return ((T) Integer.valueOf(s));
		}else if(clazz==String.class) {
			return (T) s;
		}else if(clazz==long.class||clazz==Long.class) {
			return (T) Long.valueOf(s);
		}else {
			JSONObject json=JSON.parseObject(s);
			return JSON.toJavaObject(json, clazz);
		}		
	}
	/**
	 * 將Bean對象轉換爲字符串類型
	 * @param <T>
	 */
	public static <T> String beanToString(T value) {
		//如果是null
		if(value==null) return null;
		//如果不是null
		Class<?> clazz=value.getClass();
		if(clazz==int.class||clazz==Integer.class) {
			return ""+value;
		}else if(clazz==String.class) {
			return ""+value;
		}else if(clazz==long.class||clazz==Long.class) {
			return ""+value;
		}else {
			return JSON.toJSONString(value);
		}		
	}
	private void returnToPool(Jedis jedis) {
		if(jedis!=null) {	
			jedis.close();
		}
	}
	public <T> boolean set(String key,T value){
		Jedis jedis=null;
		//在JedisPool裏面取得Jedis
		try {
			jedis=jedisPool.getResource();
			//將T類型轉換爲String類型
			String s=beanToString(value);
			if(s==null) {
				return false;
			}
			jedis.set(key, s);
			return true;
		}finally {
			returnToPool(jedis);
		}
	}
	public <T> T get(String key,Class<T> data){
		Jedis jedis=null;
		//在JedisPool裏面取得Jedis
		try {
			jedis=jedisPool.getResource();
			System.out.println("jedis:"+jedis);
			String sval=jedis.get(key);
			System.out.println("sval:"+sval);
			//將String轉換爲Bean入後傳出
			T t=stringToBean(sval,data);
			return t;
		}finally {
			returnToPool(jedis);
		}
	}	
}

注意:該類中封裝了常用的Redis 方法操作。

  1. public T get(KeyPrefix prefix,String key,Class data) 根據key取得緩存中值(根據傳入的前綴)
  2. public boolean delete(KeyPrefix prefix,String key) 刪除key
  3. public boolean set(KeyPrefix prefix,String key,T value) 根據key設置緩存中值
  4. public Long decr(KeyPrefix prefix,String key) 自減
  5. public Long incr(KeyPrefix prefix,String key) 自增
  6. public boolean exitsKey(KeyPrefix prefix,String key) 是否存在key
  7. public static T stringToBean(String s,Class clazz)
  8. public static String beanToString(T value)

但是其中,存入redis 的是String類型,這個時候我們的數據不一定是String類型,所以需要類型轉換,將數據轉換成String格式存入。
BeanToString()這個方法,就是來轉化,先獲取傳入數據的Class類型,根據類型判斷,int,long,String 類型,通過API轉換直接轉換成String即可,或是其他的自定義對象,則利用fastjson庫將我們項目中定義的JavaBean 對象,轉化爲json字符串。
StringToBean() 相當於上個是反方法。都需要傳入一個類型,這樣才知道將字符串轉換爲什麼對象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章