1. 程式人生 > >springboot專案整合reids並使用

springboot專案整合reids並使用

宣告:

此文章為springboot 2.0版本整合redis。並簡單示範,儲存redis和獲取redis中資料的方法、

此處springboot專案的搭建略過。主要記錄redis的整合和使用

整合步驟:

第一步:pom檔案新增redis依賴

            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>2.9.0</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
                <version>2.0.5.RELEASE</version>
            </dependency>

第二步:配置redis資料來源

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/marketing?characterEncoding=utf-8&verifyServerCertificate=false&useSSL=false&requireSSL=false&allowMultiQueries=true
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: marketing
    password: marketing
    type: com.zaxxer.hikari.HikariDataSource
  redis:
    host: 172.20.94.39
    password:(如果有密碼就新增密碼如果沒有就空著)
    port: 6379

 

第三步:配置jedisService或者jedisUtils

1、jedisService

import com.rrc.marketing.core.query.Query;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.exceptions.JedisConnectionException;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.Set;
import java.util.function.Function;

/**
 * JedisService
 *
 * @author lixb
 * @date 2016-11-29 下午8:24
 */
@Service
public class  JedisService {

	private final static Logger logger = LoggerFactory.getLogger(JedisService.class);

	@Value("${spring.redis.host}")
	private String host;
	@Value("${spring.redis.port}")
	private Integer port;
	@Value("${spring.redis.password}")
	private String password;

	@Value("${spring.redis.db}")
	private Integer database;

	private static JedisPool jedisPool;


	public <Q extends Query> Integer getIntegerFromRedisOrSet(Function<Q, Integer> function, Q query, String key, int expire) {
		logger.info("---getIntegerFromRedisOrSet()----, key: {}, query: {}", key, query);
		String value = getByKey(key);
		if (StringUtils.isBlank(value)) {
			Integer integer = function.apply(query);
			setByKey(key, integer + "", expire);
			return integer;
		}
		return Integer.valueOf(value);
	}

	/**
	 * 得到key中儲存的內容
	 *
	 * @param key
	 * @return
	 */
	public String getByKey(String key) {
		if (StringUtils.isBlank(key)) {
			logger.error("empty key, key {}", key);
			return null;
		}

		Object s = oper(get(key));
		return s == null ? null : s.toString();
	}

	/**
	 * 根據表示式得到一組key
	 *
	 * @param pattern
	 * @return
	 */
	public Set<String> getByPattern(String pattern) {
		if (StringUtils.isBlank(pattern)) {
			logger.error("empty pattern, pattern {}", pattern);
			return null;
		}
		Set<String> keys = (Set<String>)oper(getKeys(pattern));
		return keys;
	}

	/**
	 * 根據一組key獲取值
	 */
	public List<String> mgetByKeySet(Set<String> keySet){
		if(null == keySet || keySet.isEmpty()){
			logger.error("empty keys========");
			return null;
		}
		String[] keys = keySet.toArray(new String[keySet.size()]);
		List<String> list = (List<String>)oper(mget(keys));
		return list;
	}


	/**
	 * 設定redis的key為value,超時為expire
	 *
	 * @param key
	 * @return
	 */
	public boolean setByKey(String key, String value, int expire) {
		if (StringUtils.isBlank(key) || StringUtils.isBlank(value)) {
			logger.error("empty key or value, key {}, value {}", key, value);
			return false;
		}

		String s = oper(set(key, value, expire)).toString();
		return !(StringUtils.isBlank(s) || !s.equals("OK"));
	}

    /**
     * 設定一組key Value
     * @param keyValues
     * @return
     */
	public boolean msetByKV(String... keyValues){
        if (keyValues.length <= 0) {
            logger.error("empty keyValues");
            return false;
        }
        String s =  oper(mset(keyValues)) == null ? null : oper(mset(keyValues)).toString() ;
        return  s != null && !StringUtils.isBlank(s.toString()) && s.toString().equals("OK");
    }

	/**
	 * 設定redis的key為value,不存在時設定
	 *
	 * @param key
	 * @return
	 */
	public boolean setNxByKey(String key, String value, Integer expire) {
		if (StringUtils.isBlank(key) || StringUtils.isBlank(value) || expire == null) {
			logger.error("empty key or value, key {}, value {}, expire {}", key, value, expire);
			return false;
		}

		Object s = oper(setnx(key, value, expire));

		return s != null && !StringUtils.isBlank(s.toString()) && s.toString().equals("OK");
	}

	/**
	 * 獲取key的下一個值
	 * @param key
	 * @return
	 */
	public int getNextId(String key){
		if(setNxByKey(key, String.valueOf(0), 24*3600)){
			return 0;
		}else{
			return incByKey(key);
		}
	}

	public boolean setNxByKey(String key, String value) {
		if (StringUtils.isBlank(key) || StringUtils.isBlank(value)) {
			logger.error("empty key or value, key {}, value {}", key, value);
			return false;
		}
		Object s = oper(setnx(key, value));
		return Integer.valueOf(s.toString()).intValue() == 1;
	}

	/**
	 * 設定超時
	 *
	 * @param key
	 * @return
	 */
	public boolean setExpire(String key, Integer expire) {
		if (StringUtils.isBlank(key) || expire == null) {
			logger.error("empty key or expire, key {}, expire {}", key, expire);
			return false;
		}

		String s = oper(expire(key, expire)).toString();
		return !(StringUtils.isBlank(s) || !s.equals("1"));
	}

	/**
	 * 增加key的值
	 *
	 * @param key
	 * @return
	 */
	public int incByKey(String key) {
		if (StringUtils.isBlank(key)) {
			logger.error("empty key , key {}", key);
			return -1;
		}

		Object s = oper(inc(key, 1L));
		return s == null ? -1 : Integer.parseInt(s.toString());
	}

	public int decByKey(String key) {
		if (StringUtils.isBlank(key)) {
			logger.error("empty key , key {}", key);
			return -1;
		}

		Object s = oper(dec(key, 1L));
		return s == null ? -1 : Integer.parseInt(s.toString());
	}

	/**
	 * get redis conection
	 *
	 * @return
	 */
	private static Jedis getRedisResource() {
		if (null == jedisPool) {
			throw new NullPointerException("please connect to redis first!");
		}

		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
		} catch (JedisConnectionException e) {
			logger.error("redis connection error", e);
			return null;
		}
		return jedis;
	}

	/**
	 * apply f to jedis
	 *
	 * @param f
	 * @return
	 */
	private static Object oper(Function<Jedis, Object> f) {
		if (f == null) {
			return null;
		}
		Jedis jedis = getRedisResource();
        if (jedis == null) {
			logger.error("get resource failed");
			return null;
		}

		try {
			Object o = f.apply(jedis);
			return o;
		} catch (Exception e) {
			logger.error("redis operation failed", e);
			return null;
		} finally {
			jedis.close();
		}
	}

	@PostConstruct
	public void init() {
		logger.info("init jedis, host {}, port {}, password {}", host, port, password);
		connect(host, port, password,database);
	}

	@PreDestroy
	public void close() {
		logger.info("close jedis, host {}, port {}, password {}", host, port, password);
		if (jedisPool != null && !jedisPool.isClosed()) {
			jedisPool.close();
		}
	}

	/**
	 * connect to redis
	 *
	 * @param host
	 * @param port
	 * @param password
	 */
	private synchronized static void connect(String host, Integer port, String password,int database){
		if (jedisPool != null && !jedisPool.isClosed()) {
			return;
		} // 防止重複連線

		if (StringUtils.isEmpty(host) || port == null || port < 0 || port > 65535) {
			throw new IllegalArgumentException("redis connection error, host = " + host + ", port=" + port);
		}

		JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
		jedisPoolConfig.setMaxTotal(1000);
		jedisPoolConfig.setMaxIdle(100);
		if (StringUtils.isEmpty(password)) {
			jedisPool = new JedisPool(jedisPoolConfig, host, port, 10000,null,database);
		} else {
			jedisPool = new JedisPool(new JedisPoolConfig(), host, port, 10000, password,database);
		}

    }

	public boolean setByKey(String key, String value) {
		if (StringUtils.isBlank(key) || StringUtils.isBlank(value)) {
			logger.error("empty key or value, key {}, value {}", key, value);
			return false;
		}
		String s = oper(set(key, value, null)).toString();
		return !(StringUtils.isBlank(s) || !s.equals("OK"));
	}

	public boolean delByKey(String key) {
		if (StringUtils.isBlank(key)) {
			logger.error("empty key or value, key {}", key);
			return false;
		}
		String s = oper(del(key)).toString();
		return !(StringUtils.isBlank(s) || !s.equals("OK"));
	}

    public boolean delByKeys(String... keys) {
        if (keys.length <= 0 ) {
            logger.error("empty key or value, keys {}", keys);
            return false;
        }
        String s = oper(del(keys)).toString();
        return !(StringUtils.isBlank(s) || !s.equals("OK"));
    }

	/**
	 * 操作set集合 向名稱為key的set中新增元素member
	 * 
	 * @param key
	 * @param members
	 * @return
	 */
	public boolean addSetByKey(String key, String... members) {
		if (StringUtils.isBlank(key) || members == null || members.length <= 0) {
			logger.error("empty key or value, key {}", key);
			return false;
		}

		String s = oper(sadd(key, members)).toString();

		return !StringUtils.isBlank(s) || !s.equals("0");

	}

	/**
	 * 操作set集合 返回名稱為key的set的所有元素
	 * 
	 * @param key
	 * @return
	 */
	public Set<String> smembersByKey(String key) {
		if (StringUtils.isBlank(key)) {
			logger.error("empty key, key {}", key);
			return null;
		}

		Set<String> s = (Set<String>) oper(smembers(key));
		return s;
	}

	public Boolean existByKey(String key) {
		if (StringUtils.isBlank(key)) {
			logger.error("empty key, key {}", key);
			return false;
		}
		return (Boolean) oper(exists(key));
	}

	public static Function<Jedis, Object> get(String key) {
		if (StringUtils.isEmpty(key)) {
			throw new NullPointerException("key cannot be null");
		}
		return (Jedis jedis) -> jedis.get(key);
	}



    public static Function<Jedis, Object> mset(String... keyValues) {
	    if(keyValues.length <= 0){
	        throw new NullPointerException("keyValues 必傳");
        }
        return (Jedis jedis) -> jedis.mset(keyValues);
    }
	/**
	 * 根據主鍵設定, 不過期
	 *
	 * @param key
	 * @param value
	 * @return
	 */
	public static Function<Jedis, Object> set(String key, String value) {
		return set(key, value, null);
	}

	public static Function<Jedis, Object> del(String key) {
		return (Jedis jedis) -> jedis.del(key);
	}

    public static Function<Jedis, Object> del(String... key) {
        return (Jedis jedis) -> jedis.del(key);
    }

	/**
	 * 根據主鍵設定, expire單位為s
	 *
	 * @param key
	 * @param value
	 * @param expire
	 * @return
	 */
	public static Function<Jedis, Object> set(String key, String value, Integer expire) {
		if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
			throw new NullPointerException("key or value cannot be null");
		}
		if (expire == null) {
			return (Jedis jedis) -> jedis.set(key, value);
		} else {
			return (Jedis jedis) -> jedis.setex(key, expire, value);
		}
	}




	/**
	 * 獲取一組key值
	 *
	 * @param key
	 * @return
	 */
	public static Function<Jedis, Object> mget(String... key) {

		return (Jedis jedis) -> jedis.mget(key);
	}



	/**
	 * 獲取一組key
	 *
	 * @param pattern
	 * @return
	 */
	public static Function<Jedis, Object> getKeys(String pattern) {

		return (Jedis jedis) -> jedis.keys(pattern);
	}
	/**
	 * 根據主鍵增加Value的值
	 *
	 * @param key
	 * @param value
	 * @return
	 */
	public static Function<Jedis, Object> inc(String key, Long value) {
		if (StringUtils.isEmpty(key) || value == null) {
			throw new NullPointerException("key or value cannot be null");
		}

		return (Jedis jedis) -> jedis.incrBy(key, value);
	}
	/**
	 * 根據主鍵減少Value的值
	 *
	 * @param key
	 * @param value
	 * @return
	 */
	public static Function<Jedis, Object> dec(String key, Long value) {
		if (StringUtils.isEmpty(key) || value == null) {
			throw new NullPointerException("key or value cannot be null");
		}
		return (Jedis jedis) -> jedis.decrBy(key, value);
	}

	/**
	 * 根據主鍵設定;不存在時設定
	 *
	 * @param key
	 * @param value
	 * @return
	 */
	public static Function<Jedis, Object> setnx(String key, String value) {
		if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
			throw new NullPointerException("key or value cannot be null");
		}
		return (Jedis jedis) -> jedis.setnx(key, value);
	}

	/**
	 * 根據主鍵設定;不存在時設定,支援超時
	 *
	 * @param key
	 * @param value
	 * @return
	 */
	public static Function<Jedis, Object> setnx(String key, String value, Integer expire) {
		if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value) || expire == null) {
			throw new NullPointerException("key or value or expire cannot be null");
		}
		return (Jedis jedis) -> jedis.set(key, value, "nx", "ex", expire);
	}

	/**
	 * 設定鍵的超時時間
	 *
	 * @param key
	 * @param expire
	 * @return
	 */
	public static Function<Jedis, Object> expire(String key, Integer expire) {
		if (StringUtils.isEmpty(key) || expire == null) {
			throw new NullPointerException("key or time cannot be null");
		}
		return (Jedis jedis) -> jedis.expire(key, expire);
	}

	public static Function<Jedis, Object> sadd(String key, String... members) {
		return (Jedis jedis) -> jedis.sadd(key, members);
	}

	public static Function<Jedis, Object> smembers(String key) {
		if (StringUtils.isEmpty(key)) {
			throw new NullPointerException("key or time cannot be null");
		}
		return (Jedis jedis) -> jedis.smembers(key);
	}

	public static Function<Jedis, Object> exists(String key) {
		if (StringUtils.isEmpty(key)) {
			throw new NullPointerException("key cannot be null");
		}
		return (Jedis jedis) -> jedis.exists(key);
	}
}

jedisService使用方法:

//注入jedisService  
@Autowired
private JedisService jedisService;


//儲存資料到redis中直接呼叫jedisService方法,
//示例:存入key,value,過期時間24小時過期
jedisService.setNxByKey(key,value,24 * 60 * 60);

//獲取redis中資料通過儲存的key獲取value 如果沒有獲取到值那麼value的值為null
String Value=jedisService.getByKey(key);

注意:如果想分層儲存那麼key的規則是用":"符號分開

例如:下圖的key命名規則為:marketing:scheduler:fem:tencent:campaign:name:15501802,value值為:20180606

分層顯示就可以按層級分開值像專案的包結構一樣。

檢視redis中的資料,安裝redis視覺化工具redisdesktopmanager

安裝好之後新增連線檢視資料

 

2、jedisUtils

package com.rrc.marketing.adsscheduler.utils;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

@Component
/**
 * jedis封裝
 * 用法
 * 注入 JedisClientUtil jedisClientUtil;
 * 		Jedis jedis= jedisClientUtil.getRedisClient();
 *      獲取key
    	 jedis.get(tokenKey);
    	 //過期時間的key
    	  jedis.setex(tokenKey, 10*60, accessToken);
    	  //普通的key
    	  jedis.set(key, value);
 * @author xingxiangguo
 *
 */
public class JedisClientUtil {
	@Value("${spring.redis.host}")
	String host;
	@Value("${spring.redis.port}")
	int port;
	private byte[] temp_lock = new byte[1];
	private Jedis jedis;
	private JedisClientUtil(){};
	public Jedis getRedisClient(){
		if(jedis == null){
			synchronized (temp_lock) {
				if(jedis == null){
					jedis = new Jedis(host,port);
				}
			}
		}
		return jedis;
	}
	
}

jedisUtils的使用方法

//注入jedisClientUtil
@Autowired
public       JedisClientUtil     jedisClientUtil;

//向redis中儲存資料
 Jedis jedis = jedisClientUtil.getRedisClient();
//增加指定的值,返回操作後的值
 usedQuota = jedis.incrBy(typeKey, currentQuota);
//減少指定的值
 count =jedis.decrBy("count", 100);
//儲存一個字串
 jedis.set(nameKey, allQuota.toString());
 //設定有效期
 jedis.expireAt(typeKey, expireTime);
 jedis.expireAt(nameKey, expireTime);
 //獲取key的舊值,並給其設定新值,返回值是被修改之前的值
 String oldName=jedis.getSet("name", "Higgin");
 //獲取指定長度的字串
 jedis.getrange("name", 0, -1);
        
 //替換字串部分內容
 jedis.setrange("name", 0, "ab");
//只有key不存在的時候才進行儲存(key若已經存在不錯任何改變,返回0,若不存在,則建立一個key並賦值,返回1)
long result=jedis.setnx("name", "abc");

等等方法。請看連線jeids方法點選跳轉

jedis方法

 

存入資料同jedis一樣可以用視覺化工具檢視

 

 

結束

感謝觀看!