Redis工具类和使用操作

package com.xxl.sso.core.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

import java.io.*;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;


/**
 * Redis client base on jedis 根据继承类的不同,
 * jedis实例方式不用:JedisSimpleFactry/JedisPoolFactry/ShardedJedisPoolFactry
 * 
 * 	# for redis (sharded.jedis.address=host01:port,host02:port)
 *	sharded.jedis.address=127.0.0.1:6379,127.0.0.1:6379,127.0.0.1:6379
 */
public class JedisUtil {
	private static Logger logger = LoggerFactory.getLogger(JedisUtil.class);

	private static final int DEFAULT_EXPIRE_TIME = 7200; // 默认过期时间,单位/秒, 60*60*2=2H, 两小时
	private static String address;
	public static void init(String address){
		JedisUtil.address = address;
	}

	// ------------------------ ShardedJedisPool ------------------------
	/**
	 *	方式01: Redis单节点 + Jedis单例 : Redis单节点压力过重, Jedis单例存在并发瓶颈 》》不可用于线上
	 * 		new Jedis("127.0.0.1", 6379).get("cache_key");
	 *	方式02: Redis单节点 + JedisPool单节点连接池 》》 Redis单节点压力过重,负载和容灾比较差
	 * 		new JedisPool(new JedisPoolConfig(), "127.0.0.1", 6379, 10000).getResource().get("cache_key");
	 *  方式03: Redis集群(通过client端集群,一致性哈希方式实现) + Jedis多节点连接池 》》Redis集群,负载和容灾较好, ShardedJedisPool一致性哈希分片,读写均匀,动态扩充
	 *  	new ShardedJedisPool(new JedisPoolConfig(), new LinkedList<JedisShardInfo>());
     */

	private static ShardedJedisPool shardedJedisPool;
	private static ReentrantLock INSTANCE_INIT_LOCL = new ReentrantLock(false);

	/**
	 * 获取ShardedJedis实例
	 * @return
	 */
	private static ShardedJedis getInstance() {
		if (shardedJedisPool == null) {
			try {
				if (INSTANCE_INIT_LOCL.tryLock(2, TimeUnit.SECONDS)){

					try {

						if (shardedJedisPool == null) {
							// JedisPoolConfig
							JedisPoolConfig config = new JedisPoolConfig();
							config.setMaxTotal(200);			// 最大连接数, 默认8个
							config.setMaxIdle(50);				// 最大空闲连接数, 默认8个
							config.setMinIdle(8);				// 设置最小空闲数
							config.setMaxWaitMillis(10000);		// 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
							config.setTestOnBorrow(true);		// 在获取连接的时候检查有效性, 默认false
							config.setTestOnReturn(true);       // 调用returnObject方法时,是否进行有效检查
							config.setTestWhileIdle(true);		// Idle时进行连接扫描
							config.setTimeBetweenEvictionRunsMillis(30000);	//表示idle object evitor两次扫描之间要sleep的毫秒数
							config.setNumTestsPerEvictionRun(10);			//表示idle object evitor每次扫描的最多的对象数
							config.setMinEvictableIdleTimeMillis(60000);	//表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义

							// JedisShardInfo List
							List<JedisShardInfo> jedisShardInfos = new LinkedList<JedisShardInfo>();

							String[] addressArr = address.split(",");
							for (int i = 0; i < addressArr.length; i++) {
								String[] addressInfo = addressArr[i].split(":");
								String host = addressInfo[0];
								int port = Integer.valueOf(addressInfo[1]);
								JedisShardInfo jedisShardInfo = new JedisShardInfo(host, port, 10000);
								jedisShardInfos.add(jedisShardInfo);
							}
							shardedJedisPool = new ShardedJedisPool(config, jedisShardInfos);
							logger.info(">>>>>>>>>>> xxl-sso, JedisUtil.ShardedJedisPool init success.");
						}

					} finally {
						INSTANCE_INIT_LOCL.unlock();
					}
                }

			} catch (InterruptedException e) {
				logger.error(e.getMessage(), e);
			}
		}

		if (shardedJedisPool == null) {
			throw new NullPointerException(">>>>>>>>>>> xxl-sso, JedisUtil.ShardedJedisPool is null.");
		}

		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		return shardedJedis;
	}

	// ------------------------ serialize and unserialize ------------------------
	/**
	 * 将对象-->byte[] (由于jedis中不支持直接存储object所以转换成byte[]存入)
	 *
	 * @param object
	 * @return
	 */
	private static byte[] serialize(Object object) {
		ObjectOutputStream oos = null;
		ByteArrayOutputStream baos = null;
		try {
			// 序列化
			baos = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(baos);
			oos.writeObject(object);
			byte[] bytes = baos.toByteArray();
			return bytes;
		} catch (Exception e) {
			logger.error("{}", e);
		} finally {
			try {
				oos.close();
				baos.close();
			} catch (IOException e) {
				logger.error("{}", e);
			}
		}
		return null;
	}

	/**
	 * 将byte[] -->Object
	 *
	 * @param bytes
	 * @return
	 */
	private static Object unserialize(byte[] bytes) {
		ByteArrayInputStream bais = null;
		try {
			// 反序列化
			bais = new ByteArrayInputStream(bytes);
			ObjectInputStream ois = new ObjectInputStream(bais);
			return ois.readObject();
		} catch (Exception e) {
			logger.error("{}", e);
		} finally {
			try {
				bais.close();
			} catch (IOException e) {
				logger.error("{}", e);
			}
		}
		return null;
	}

	// ------------------------ jedis util ------------------------
	/**
	 * 存储简单的字符串或者是Object 因为jedis没有分装直接存储Object的方法,所以在存储对象需斟酌下
	 * 存储对象的字段是不是非常多而且是不是每个字段都用到,如果是的话那建议直接存储对象,
	 * 否则建议用集合的方式存储,因为redis可以针对集合进行日常的操作很方便而且还可以节省空间
	 */

	/**
	 * Set String
	 * @param key
	 * @param value
	 * @param seconds	存活时间,单位/秒
	 * @return
	 */
	public static String setStringValue(String key, String value, int seconds) {
		String result = null;
		ShardedJedis client = getInstance();
		try {
			result = client.setex(key, seconds, value);
		} catch (Exception e) {
			logger.info("{}", e);
		} finally {
			client.close();
		}
		return result;
	}

	/**
	 * Set String (默认存活时间, 2H)
	 * @param key
	 * @param value
	 * @return
	 */
	public static String setStringValue(String key, String value) {
		return setStringValue(key, value, DEFAULT_EXPIRE_TIME);
	}

	/**
	 * Set Object
	 *
	 * @param key
	 * @param obj
	 * @param seconds	存活时间,单位/秒
	 */
	public static String setObjectValue(String key, Object obj, int seconds) {
		String result = null;
		ShardedJedis client = getInstance();
		try {
			result = client.setex(key.getBytes(), seconds, serialize(obj));
		} catch (Exception e) {
			logger.info("{}", e);
		} finally {
			client.close();
		}
		return result;
	}

	/**
	 * Set Object (默认存活时间, 2H)
	 * @param key
	 * @param obj
	 * @return
	 */
	public static String setObjectValue(String key, Object obj) {
		return setObjectValue(key, obj, DEFAULT_EXPIRE_TIME);
	}

	/**
	 * Get String
	 * @param key
	 * @return
	 */
	public static String getStringValue(String key) {
		String value = null;
		ShardedJedis client = getInstance();
		try {
			value = client.get(key);
		} catch (Exception e) {
			logger.info("", e);
		} finally {
			client.close();
		}
		return value;
	}

	/**
	 * Get Object
	 * @param key
	 * @return
	 */
	public static Object getObjectValue(String key) {
		Object obj = null;
		ShardedJedis client = getInstance();
		try {
			byte[] bytes = client.get(key.getBytes());
			if (bytes != null && bytes.length > 0) {
				obj = unserialize(bytes);
			}
		} catch (Exception e) {
			logger.info("", e);
		} finally {
			client.close();
		}
		return obj;
	}

	/**
	 * Delete
	 * @param key
	 * @return Integer reply, specifically:
	 * 		an integer greater than 0 if one or more keys were removed
	 *      0 if none of the specified key existed
	 */
	public static Long del(String key) {
		Long result = null;
		ShardedJedis client = getInstance();
		try {
			result = client.del(key);
		} catch (Exception e) {
			logger.info("{}", e);
		} finally {
			client.close();
		}
		return result;
	}

	/**
	 * incrBy	value值加i
	 * @param key
	 * @param i
	 * @return new value after incr
	 */
	public static Long incrBy(String key, int i) {
		Long result = null;
		ShardedJedis client = getInstance();
		try {
			result = client.incrBy(key, i);
		} catch (Exception e) {
			logger.info("{}", e);
		} finally {
			client.close();
		}
		return result;
	}

	/**
	 * exists
	 * @param key
	 * @return Boolean reply, true if the key exists, otherwise false
	 */
	public static boolean exists(String key) {
		Boolean result = null;
		ShardedJedis client = getInstance();
		try {
			result = client.exists(key);
		} catch (Exception e) {
			logger.info("{}", e);
		} finally {
			client.close();
		}
		return result;
	}

	/**
	 * expire	重置存活时间
	 * @param key
	 * @param seconds	存活时间,单位/秒
	 * @return Integer reply, specifically:
	 * 		1: the timeout was set.
	 * 		0: the timeout was not set since the key already has an associated timeout (versions lt 2.1.3), or the key does not exist.
	 */
	public static long expire(String key, int seconds) {
		Long result = null;
		ShardedJedis client = getInstance();
		try {
			result = client.expire(key, seconds);
		} catch (Exception e) {
			logger.info("{}", e);
		} finally {
			client.close();
		}
		return result;
	}

	/**
	 * expireAt		设置存活截止时间
	 * @param key
	 * @param unixTime		存活截止时间戳
	 * @return
	 */
	public static long expireAt(String key, long unixTime) {
		Long result = null;
		ShardedJedis client = getInstance();
		try {
			result = client.expireAt(key, unixTime);
		} catch (Exception e) {
			logger.info("{}", e);
		} finally {
			client.close();
		}
		return result;
	}

	public static void main(String[] args) {
		init("127.0.0.1:6379");

		setObjectValue("key", "666");
		System.out.println(getObjectValue("key"));

	}
}

2.在项目启动前加载初始化redis

package com.xxl.sso.server.core.config;

import com.xxl.sso.core.util.JedisUtil;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;


@Configuration
public class RedisConfig implements InitializingBean {

    @Value("${redis.address}")
    private String redisAddress;

    @Override
    public void afterPropertiesSet() throws Exception {
        JedisUtil.init(redisAddress);
    }

}

3.在资源文件下添加redis.address地址

redis.address=127.0.0.1:6379

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,下面是一个使用 Python 实现的 Redis 工具类的示例: ```python import redis class RedisUtil: def __init__(self, host='localhost', port=6379, db=0, password=None): self.redis = redis.Redis(host=host, port=port, db=db, password=password) def set(self, key, value, ex=None): self.redis.set(key, value, ex=ex) def get(self, key): return self.redis.get(key) def delete(self, key): self.redis.delete(key) def expire(self, key, seconds): self.redis.expire(key, seconds) ``` 该工具类使用了 Python 的 `redis` 库,它提供了一个高级的 Redis 客户端,可以方便地连接到 Redis 服务器并执行 Redis 命令。 该工具类定义了四个方法: - `set` 方法用于向 Redis 服务器设置一个键值对。 - `get` 方法用于从 Redis 服务器获取一个键的值。 - `delete` 方法用于从 Redis 服务器删除一个键。 - `expire` 方法用于设置一个键的过期时间(以秒为单位)。 使用这个工具类,你可以方便地连接到 Redis 服务器并执行 Redis 命令,例如: ```python redis_util = RedisUtil() redis_util.set('key', 'value') value = redis_util.get('key') print(value) ``` 希望这对你有帮助! ### 回答2: 使用Python实现一个Redis工具类可以方便地封装对Redis数据库的操作,简化开发工作。 首先,需要在Python中使用Redis模块连接到Redis数据库。可以使用`redis`模块中的`StrictRedis`类进行连接和操作。 接下来,可以定义一个Redis工具类,包含常用的Redis操作方法。例如,可以包含以下几个方法: 1. 连接Redis数据库的方法:可以使用`StrictRedis`类的构造函数创建一个Redis连接对象。 ```python import redis class RedisTool: def __init__(self, host='localhost', port=6379, password=None, db=0): self.redis = redis.StrictRedis(host=host, port=port, password=password, db=db) ``` 2. 存储数据的方法:可以使用`set`方法将数据存储到Redis中。 ```python def set_data(self, key, value): self.redis.set(key, value) ``` 3. 获取数据的方法:可以使用`get`方法从Redis中获取数据。 ```python def get_data(self, key): value = self.redis.get(key) return value.decode() if value else None ``` 4. 删除数据的方法:可以使用`delete`方法从Redis中删除指定的数据。 ```python def delete_data(self, key): self.redis.delete(key) ``` 5. 判断key是否存在的方法:可以使用`exists`方法判断指定的key是否存在。 ```python def exists_key(self, key): return self.redis.exists(key) ``` 通过封装这些常用的Redis操作方法,可以提高开发效率,减少重复代码。 使用这个Redis工具类,可以轻松地连接到Redis数据库并使用常用的操作。在其他程序中,只需要实例化Redis工具类,然后调用相关方法即可完成所需的Redis操作。 ### 回答3: REDIS是一个开源的内存数据库,主要用于存储和检索数据。在PYTHON中,我们可以使用redis-py库来实现一个REDIS工具类。 首先,我们需要安装redis-py库。在命令行中输入以下命令来安装库: ``` pip install redis ``` 接下来,我们可以在PYTHON中创建一个REDIS工具类,实现常用的功能方法。以下是一个简单的示例: ```python import redis class RedisUtils: def __init__(self, host, port, db): self.redis = redis.Redis(host=host, port=port, db=db) def set_key(self, key, value): self.redis.set(key, value) def get_key(self, key): return self.redis.get(key) def delete_key(self, key): return self.redis.delete(key) def get_keys(self, pattern='*'): return self.redis.keys(pattern) def increment(self, key): self.redis.incr(key) def decrement(self, key): self.redis.decr(key) ``` 在上面的示例中,我们创建了一个RedisUtils类,它有一个初始化方法来连接到REDIS服务器。我们可以通过set_key方法来设置键值对,通过get_key方法来获取键对应的值,通过delete_key方法来删除键,通过get_keys方法来获取匹配模式的键列表,通过increment和decrement方法来对键进行自增和自减操作使用这个REDIS工具类,我们可以方便地与REDIS服务器进行交互。可以根据实际需求,添加更多的功能方法。 注意,以上仅为一个简单的示例,实际使用中可能需要更复杂的功能方法和错误处理。在实际开发中,还可以根据需要进行更多的封装和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值