SpringBoot中搭建Redis缓存

(一)SpringBoot中搭建Redis缓存

这篇文章讲述如何在Springboot中搭建redis,按照以下步骤进行


 1)、以下链接 是如何在window本地搭建redis进行测试

https://blog.youkuaiyun.com/qq_29434911/article/details/79876580

注意:在导入jedis-2.6.2.jar、spring-data-redis-1.4.2.RELEASE.jar  如果你下载的版本太低可能会提示版本有误(解决方法只要重新下一个高版本就行了),我这个版本应该是没错的。之前
spring-data-redis-1.4.2.RELEASE.jar 我是下载1.0.0所以太低了。

 2)在Springboot运用redis方法进行缓存操作

           第一步:在pom.xml文件中配置redis

		<!--redis配置-->  
		<dependency>  
		    <groupId>org.springframework.boot</groupId>  
		    <artifactId>spring-boot-starter-redis</artifactId>  <!-- 可以不需要加入版本号 -->
		</dependency>  
		
		 <dependency>
     		<groupId>redis.clients</groupId>
     		<artifactId>jedis</artifactId>
    		 <version>2.5.2</version>
 		</dependency>


         第二步:初始化Redis连接池 ,操作redis

          CacheKit.java:         

package com.zcwl.redis;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.exceptions.JedisConnectionException;

public class CacheKit {
	
	private static Logger logger = LoggerFactory.getLogger(CacheKit.class);  
	
	private List<JSONObject> resultList;  
	
	private static JedisPool pool;  
	
	
	 /** 
     * 初始化Redis连接池 
     */  
    private static void initializePool() {  
        //redisURL 与 redisPort 的配置文件  
  
        JedisPoolConfig config = new JedisPoolConfig();  
        //设置最大连接数(100个足够用了,没必要设置太大)  
        config.setMaxTotal(100);  
        //最大空闲连接数  
        config.setMaxIdle(10);  
        //获取Jedis连接的最大等待时间(50秒)   
        config.setMaxWaitMillis(50 * 1000);  
        //在获取Jedis连接时,自动检验连接是否可用  
        config.setTestOnBorrow(true);  
        //在将连接放回池中前,自动检验连接是否有效  
        config.setTestOnReturn(true);  
        //自动测试池中的空闲连接是否都是可用连接  
        config.setTestWhileIdle(true);
        //创建连接池  
        //pool = new JedisPool(config, "120.88.166.244",6379);	//连接阿里云服务器上面的缓存(如果本地在使用地址,本地运行将会把本地缓存数据同步在线上缓存中)
        pool = new JedisPool(config, "127.0.0.1",6379);	//本地缓存(更新需要将这个注释起来,解开上面地址)
    }
    

    /** 
     * 多线程环境同步初始化(保证项目中有且仅有一个连接池) 
     */  
    private static synchronized void poolInit() {  
        if (null == pool) {  
            initializePool();  
        }  
    } 
    
    /** 
     * 获取Jedis实例 
     */  
    private static Jedis getJedis() {  
        if (null == pool) {  
            poolInit();  
        }  
  
        int timeoutCount = 0;  
        while (true) {
            try {  
                if (null != pool) {  
                    return pool.getResource();  
                }  
            } catch (Exception e) {  
                if (e instanceof JedisConnectionException) {  
                    timeoutCount++;  
                    logger.warn("getJedis timeoutCount={}", timeoutCount);  
                    if (timeoutCount > 3) {  
                        break;  
                    }  
                } else {  
                   /* logger.warn("jedisInfo ... NumActive=" + pool.getResource().get("")
                            + ", NumIdle=" + pool.getNumIdle()  
                            + ", NumWaiters=" + pool.getNumWaiters()  
                            + ", isClosed=" + pool.isClosed());  */
                	logger.warn(pool.getResource()+"//"+pool);
                    logger.error("GetJedis error,", e);  
                    break;  
                }  
            }
            break;  
        }
        return null;  
    }  
    
    
    /** 
     * 释放Jedis资源 
     * 
     * @param jedis 
     */  
    private static void returnResource(Jedis jedis) {  
        if (null != jedis) {  
            pool.returnResourceObject(jedis);  
        }  
    }
    
    /** 
     * 绝对获取方法(保证一定能够使用可用的连接获取到 目标数据) 
     * Jedis连接使用后放回  
     * @param key 
     * @return 
     */  
    private String safeGet(String key) {  
        Jedis jedis = getJedis();  
        while (true) {  
            if (null != jedis) {  
                break;  
            } else {  
                jedis = getJedis();  
            }  
        }  
        String value = jedis.get(key);  
        returnResource(jedis);  
        return value;  
    }
    
    
    /** 
     * 绝对设置方法(保证一定能够使用可用的链接设置 数据) 
     * Jedis连接使用后返回连接池 
     * @param key 
     * @param time 
     * @param value 
     */  
    public void safeSet(String key, int time, String value) {  
        Jedis jedis = getJedis();  
        while (true) {  
            if (null != jedis) {  
                break;  
            } else {  
                jedis = getJedis();  
            }  
        }  
        jedis.setex(key, time, value);  
        returnResource(jedis);  
    }  
    
    /** 
     * 绝对删除方法(保证删除绝对有效) 
     * Jedis连接使用后返回连接池</span> 
     * @param key 
     */  
    private void safeDel(String key) {  
        Jedis jedis = getJedis();  
        while (true) {  
            if (null != jedis) {  
                break;  
            } else {  
                jedis = getJedis();  
            }  
        }  
        jedis.del(key);  
        returnResource(jedis);  
    }
    
    /**
     * 清除所有缓存
     */
    private static void clearCache(){
    	CacheKit kit = new CacheKit();
    	Jedis jedis = getJedis();  
    	while (true) {  
    		if (null != jedis) {  
    			break;  
    		} else {  
    			jedis = getJedis();  
    		}  
    	}
       //PS:redis默认有一些key已经存在里面,不能删除,所以后面在添加key的时候用一个统一的标识符这样将自己添加的删除
    	Iterator it = jedis.keys("redis*").iterator();	//带*号清除所有,如果写有前缀就匹配出来sy*
    	while (it.hasNext()) {
    		String key = (String) it.next();
    		kit.delByCache(key);	//删除key
    		logger.info(new Date()+":将redis缓存"+key+"值删除成功!");
    	}
    	returnResource(jedis); 
	}
    
    
    /**自定义的一些 get set del 方法,方便使用  在其他地方直接调用**/  
    public JSONObject getByCache(String key) {
        String result = safeGet(key);  
        if (result != null) {  
            return (JSONObject) JSONObject.parse(result);  
        }  
        return null;  
    }
  
    public String getByCacheToString(String key) {
        String result = safeGet(key);  
        if (result != null) {  
            return result;  
        }  
        return null;  
  
    }  
  
    public List<JSONObject> getArrayByCache(String key) {  
        String result = safeGet(key);  
        if (result != null) {  
            resultList = JSONArray.parseArray(result, JSONObject.class);  
            return resultList;  
        }  
        return null;  
    }  
  
    public JSONArray getJSONArrayByCache(String key) {  
        String result = safeGet(key);  
        if (result != null) {  
            return JSONArray.parseArray(result);  
        }  
        return null;  
    }  
  
    public void setByCache(String key, String s) {  
        safeSet(key, 86400, s);  
    }  
  
    public void setByCacheOneHour(String key, String s) {  
        safeSet(key, 3600, s);  
    }  
  
    public void setByCacheOneHour(String key, List<JSONObject> json) {  
        safeSet(key, 86400, JSONObject.toJSONString(json));  
        resultList = json;  
    }  
  
    public void setByCache(String key, JSONObject json) {  
        safeSet(key, 86400, JSONObject.toJSONString(json));  
    }  
  
    public void setByCache(String key, List<JSONObject> list) {  
        safeSet(key, 86400, JSONObject.toJSONString(list));  
        resultList = list;  
    }  
  
    public void setByCache(String key, JSONArray array) {  
        safeSet(key, 86400, JSONArray.toJSONString(array));  
    }  
  
    public void setByCacheCusTime(String key, String s, int time) {  
        safeSet(key, time, s);  
    }  
  
    public void delByCache(String key) {
    	//该方法删除指定的key
        if (null != safeGet(key)) {  
            safeDel(key);  
        }  
    }
    
    //该方法用来清除所有相关redis的key
    public void delRedisRelevantKey(){
    	clearCache();
    }
  
    public JSONObject toJSON(JSONObject db) {
        return (JSONObject) JSONObject.toJSON(db);  
    }  
  
    public List<JSONObject> toJSON(List<JSONObject> list) {
        List<JSONObject> json = new ArrayList<>();  
        for (JSONObject aList : list) {  
            json.add((JSONObject) JSONObject.toJSON(aList));  
        }
        return json;  
    }  
  
    public boolean notNull() {
        return resultList != null && resultList.size() > 0;  
    }  
  
    public List<JSONObject> getResult() {
        return resultList;
    }
    
    public static void main(String[] args) {
    	//clearCache();  到这里自己去测试一下是否可以
	}

}

之前看过其它大神的文章,都是将缓存地址放到application.properties、还有什么application.yml里面,但是我试过到我这里取不到地址,试过很多方式取不到所以才决定地址放到外面,我个人觉得影响应该不会很大。

里面也写了很多公共方法方便调用管理。如果这里测试没问题那就运用到业务流程存储数据。

RedisUtil.java   

这个类用来写redis公共方法

package com.zcwl.redis;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zcwl.goods.dto.GoodsBrand;

import net.sf.json.JSONObject;

/**
 * redis缓存公共方法
 * @author Liangth
 */

public class RedisUtil {
	
	private static Logger log = LoggerFactory.getLogger(RedisUtil.class);  
	
	//redisSyIndexBrand    命名分解  redis(用来清除缓存时候,查找) SY(代表首页比如商城:SC) 后面随机变化
	private static final String index_Brand = "redisSyIndexBrand";		//首页推荐品牌
	
	private static CacheKit kit = new CacheKit();
	
	/**
	 * 首页推荐品牌
	 * start
	 */
	//缓存数据
	public void saveIndexBrand(List<GoodsBrand> goodsBrand){
		try {
			List<JSONObject> array = new ArrayList<JSONObject>();
			for (int i = 0; i < goodsBrand.size(); i++) {
				JSONObject object = new JSONObject();
				object.put("id", goodsBrand.get(i).getId());
				object.put("brandName", goodsBrand.get(i).getBrandName());
				object.put("brandImg", goodsBrand.get(i).getBrandImg());
				if(goodsBrand.get(i).getCountryImgUrl()==null){
					object.put("countryImgUrl", "");	
				}else{
					object.put("countryImgUrl", goodsBrand.get(i).getCountryImgUrl());
				}
				object.put("specialType", goodsBrand.get(i).getSpecialType());
				array.add(object);
			}
			kit.setByCache(index_Brand, array.toString());
			log.info(new Date()+":缓存数据首页推荐品牌成功。key:"+index_Brand);
		} catch (Exception e) {
			log.error("数据缓存首页推荐品牌异常,请检查RedisUtil方法!。key:"+index_Brand);
		}
	}
	
	//读取缓存
	public List<GoodsBrand> readIndexBrand(){
		List<GoodsBrand> goodsBrand = new ArrayList<GoodsBrand>();
		try {
			List<com.alibaba.fastjson.JSONObject> list = kit.getArrayByCache(index_Brand);
			for (int i = 0; i < list.size(); i++) {
				GoodsBrand brand = new GoodsBrand();
				brand.setId(Integer.parseInt(list.get(i).get("id").toString()));
				brand.setBrandName(list.get(i).get("brandName").toString());
				brand.setBrandImg(list.get(i).get("brandImg").toString());
				if(list.get(i).get("countryImgUrl").toString() != null){
					brand.setCountryImgUrl(list.get(i).get("countryImgUrl").toString());
				}else{
					brand.setCountryImgUrl("");
				}
				brand.setSpecialType(list.get(i).get("specialType").toString());
				goodsBrand.add(brand);
			}
			log.info(new Date()+":读取缓存数据首页推荐品牌成功。key:"+index_Brand);
		} catch (Exception e) {
			// TODO: handle exception
			log.error("读取缓存首页推荐品牌异常,请检查RedisUtil方法!。key:"+index_Brand);
		}
		return goodsBrand;
	}
	
	/**
	 * end
	 */
	
}

注意:redis数据结构以key-value存储,所以将自己的数据结构转换成这种方式去存储,


3):在控制器里面去调用上面接口


这里应该都看得懂,我就不解释啦。里面有打印那些提示,在控制台查看缓存功能是不是成功了!


4)清除缓存

我这里暂时没有做到数据库和redis数据的实时同步。

现在有两个方案可以更新:

            (1)如果后台改动数据需要马上更新,那我们就可以在前台触发事件来调用后台清理缓存接口

            (2)还有设置一个定时器调用接口,到某个时间段来同步数据




阿里云服务器安装Redis及基本配置

请关注下一篇文章



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值