package cc.zeelan.framework.utils.redis;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import cc.zeelan.framework.utils.reason.R;
/**
* spring redis客户端集成
*
* @author witts
* @project core-utils
* @package cc.zeelan.framework.redis
* @version 1.0
* @message 林花谢了春红,太匆匆。无奈朝来寒雨,晚来风
*/
public class JedisUtils {
private static final Logger logger = LoggerFactory.getLogger(JedisUtils.class);
private static JedisUtils instance = null;
private static ApplicationContext context = new ClassPathXmlApplicationContext("redis/spring-redis.xml");
public static RedisTemplate<String, Object> template = null;
@SuppressWarnings("unchecked")
public JedisUtils() {
if (template == null) {
template = (RedisTemplate<String, Object>) context.getBean(RedisTemplate.class);
}
}
private static synchronized void syncInit() {
if (instance == null) {
instance = new JedisUtils();
}
}
static {
if (instance == null) {
syncInit();
}
}
/**
* 检查是否连接成功
*
* @return
*/
public String ping() {
try {
return template.execute(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection) throws DataAccessException {
return connection.ping();
}
});
} catch (Exception e) {
logger.debug("Redis 拒绝连接 (Connection refused)");
}
return null;
}
/**
* 查看redis里有多少数据
*/
public long dbSize() {
try {
return template.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection) throws DataAccessException {
return connection.dbSize();
}
});
} catch (Exception e) {
logger.debug("Redis dbSize TIME OUT");
}
return 0;
}
/**
* 清空redis 所有数据
*
* @return
*/
public String flushDB() {
try {
return template.execute(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection) throws DataAccessException {
connection.flushDb();
return "sussess";
}
});
} catch (Exception e) {
logger.debug("redis(清空数据仓异常)");
}
return "fail";
}
/**
* 根据key获取过期时间
*/
public long getTimeKey(String key) {
try {
return template.getExpire(key);
} catch (Exception e) {
logger.debug("redis(getTimeKey exception)");
}
return 0;
}
/**
* 获取key有效时间
*/
public long getTimeKey(String key, int type) {
// stringRedisTemplate.getExpire("test",TimeUnit.SECONDS)//根据key获取过期时间并换算成指定单位
long result = 0;
try {
switch (type) {
case 0:// 纳秒生效
result = template.getExpire(key, TimeUnit.NANOSECONDS);
break;
case 1:// 微妙生效
result = template.getExpire(key, TimeUnit.MICROSECONDS);
break;
case 2:// 毫秒生效
result = template.getExpire(key, TimeUnit.MILLISECONDS);
break;
case 3:// 秒生效
result = template.getExpire(key, TimeUnit.SECONDS);
break;
case 4:// 分钟生效
result = template.getExpire(key, TimeUnit.MINUTES);
break;
case 5:// 小时生效
result = template.getExpire(key, TimeUnit.HOURS);
break;
case 6:// 天生效
result = template.getExpire(key, TimeUnit.DAYS);
break;
default:// 默认秒生效
result = template.getExpire(key, TimeUnit.SECONDS);
break;
}
} catch (Exception e) {
logger.debug("redis(getTimeKey exception)");
}
return result;
}
/**
* 通过key删除
*
* @param key
*/
public long deleteByKey(String... keys) {
try {
return template.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection) throws DataAccessException {
long result = 0;
for (int i = 0; i < keys.length; i++) {
result = connection.del(keys[i].getBytes());
}
return result;
}
});
} catch (Exception e) {
logger.debug("redis(deleteByKey exception)");
}
return 0;
}
/**
* 检查key是否已经存在
*
* @param key
* @return
*/
public boolean exists(String key) {
return template.execute(new RedisCallback<Boolean>() {
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
return connection.exists(key.getBytes());
}
});
}
/**
* 设置key
*/
public boolean setKey(String key, Object value) {
try {
ValueOperations<String, Object> operation = null;
operation = template.opsForValue();
operation.set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* Redis中有个INCR和INCRBY命令, 都可以实现值递增的原子性操作, 方便了解决了高并发时的冲突问题
*
* @param key
* @param size
* @return
*/
public long increment(byte[] key, int size) {
try {
return template.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection) throws DataAccessException {
return connection.incrBy(key, size);
}
});
} catch (Exception e) {
logger.debug("Redis 拒绝连接 (Connection refused)");
}
return 0;
}
/**
* 设置key的过期时间
*/
public boolean expire(String key, long timeout, int type) {
boolean result = false;
switch (type) {
case 0:// 纳秒失效
result = template.expire(key, timeout, TimeUnit.NANOSECONDS);
break;
case 1:// 微妙失效
result = template.expire(key, timeout, TimeUnit.MICROSECONDS);
break;
case 2:// 毫秒失效
result = template.expire(key, timeout, TimeUnit.MILLISECONDS);
break;
case 3:// 秒失效
result = template.expire(key, timeout, TimeUnit.SECONDS);
break;
case 4:// 分钟失效
result = template.expire(key, timeout, TimeUnit.MINUTES);
break;
case 5:// 小时失效
result = template.expire(key, timeout, TimeUnit.HOURS);
break;
case 6:// 天失效
result = template.expire(key, timeout, TimeUnit.DAYS);
break;
default:// 默认秒失效
result = template.expire(key, timeout, TimeUnit.SECONDS);
break;
}
return result;
}
/**
* 设置数据有效时间
*
* @param key
* @param value
* @param second
* 时间参数
* @param type
* 0t纳秒/1t微秒/2t毫秒/3t秒/4t分钟/5t小时/6t天生效
*/
public void setTimeKey(String key, Object value, long second, int type) {
ValueOperations<String, Object> operation = null;
operation = template.opsForValue();
switch (type) {
case 0:// 纳秒生效
operation.set(key, value, second, TimeUnit.NANOSECONDS);
template.expire(key, second, TimeUnit.NANOSECONDS);
break;
case 1:// 微妙生效
operation.set(key, value, second, TimeUnit.MICROSECONDS);
template.expire(key, second, TimeUnit.MICROSECONDS);
break;
case 2:// 毫秒生效
operation.set(key, value, second, TimeUnit.MILLISECONDS);
template.expire(key, second, TimeUnit.MILLISECONDS);
break;
case 3:// 秒生效
operation.set(key, value, second, TimeUnit.SECONDS);
template.expire(key, second, TimeUnit.SECONDS);
break;
case 4:// 分钟生效
operation.set(key, value, second, TimeUnit.MINUTES);
template.expire(key, second, TimeUnit.MINUTES);
break;
case 5:// 小时生效
operation.set(key, value, second, TimeUnit.HOURS);
template.expire(key, second, TimeUnit.HOURS);
break;
case 6:// 天生效
operation.set(key, value, second, TimeUnit.DAYS);
template.expire(key, second, TimeUnit.DAYS);
break;
default:// 默认秒生效
operation.set(key, value, second, TimeUnit.SECONDS);
template.expire(key, second, TimeUnit.SECONDS);
break;
}
}
/**
* 获取key
*
* @param key
* @return
*/
public Object getKey(String key) {
ValueOperations<String, Object> operation = null;
operation = template.opsForValue();
return operation.get(key);
}
/**
* 设置hash集合 map为hashMap<String,Object>();
*/
public void setHashOperations(String key, Map<String, Object> value) {
HashOperations<String, Object, Object> operation = null;
operation = template.opsForHash();
operation.putAll(key, value);
operation = null;
}
/**
* 获取hash集合
*
* @param key
* @return
*/
public Map<Object, Object> getHashOperations(String key) {
HashOperations<String, Object, Object> operation = null;
operation = template.opsForHash();
return operation.entries(key);
}
/**
* 批量把一个集合插入到列表中
*
* @param key
* @param list
*/
public void setLeftArray(String key, List<Object> value) {
ListOperations<String, Object> operation = null;
operation = template.opsForList();
operation.leftPushAll(key, value);
}
/**
* 从存储在键中的列表中删除等于值的元素的第一个计数事件。 计数参数以下列方式影响操作: count> 0:删除等于从头到尾移动的值的元素。 count
* <0:删除等于从尾到头移动的值的元素。 count = 0:删除等于value的所有元素。
*
* @param key
* @param count
* @param value
*/
public long removeListKey(String key, int count, Object value) {
ListOperations<String, Object> operation = null;
operation = template.opsForList();
return operation.remove(key, count, value);
}
/**
* 获取集合长度
*/
public long getSize(String key) {
ListOperations<String, Object> opsForList = null;
opsForList = template.opsForList();
return opsForList.size(key);
}
/**
* 根据下表获取列表中的值,下标是从0开始的
*
* @param key
* @param start
* @param end
* @return
*/
public List<Object> getIndex(String key, long start, long end) {
ListOperations<String, Object> operation = null;
operation = template.opsForList();
List<Object> array = null;
array = operation.range(key, start, end);
return array;
}
/**
* 根据下表获取列表中的值,下标是从0开始的
*
* @param key
* @param start
* @param end
* @return
*/
public Object getIndex(String key, long index) {
ListOperations<String, Object> operation = null;
operation = template.opsForList();
Object object = null;
object = operation.index(key, index);
return object;
}
/**
* hash删除
*
* @return
*/
public long delete() {
HashOperations<String, Object, Object> operation = null;
operation = template.opsForHash();
return operation.delete("redisHash", "name");
}
/**
* 检测hash key是否存在
*
* @param key
* @param value
* @return
*/
public boolean hashKey(String key, String value) {
HashOperations<String, Object, Object> operation = null;
operation = template.opsForHash();
return operation.hasKey(key, value);
}
/**
* 通过给定的delta增加散列hashKey的值(整型)
*
* @return
*/
public long increment(String key, String hashKey, int number) {
HashOperations<String, Object, Object> operation = null;
operation = template.opsForHash();
return operation.increment(key, hashKey, number);
}
/**
* 通过给定的delta增加散列hashKey的值(浮点数)
*
* @param key
* @param hashKey
* @param delta
* @return
*/
public double increment(String key, String hashKey, double delta) {
HashOperations<String, Object, Object> operation = null;
operation = template.opsForHash();
return operation.increment(key, hashKey, delta);
}
/**
* 获取key所对应的散列表的key
*
* @param key
* @return
*/
public Set<Object> keys(String key) {
HashOperations<String, Object, Object> operation = null;
operation = template.opsForHash();
return operation.keys(key);
}
/**
* 获取key所对应的散列表的大小个数
*
* @param key
* @return
*/
public long size(String key) {
HashOperations<String, Object, Object> operation = null;
operation = template.opsForHash();
return operation.size(key);
}
/**
* 设置散列hashKey的值
*
* @param key
* @param hashKey
* @param value
*/
public void put(String key, String hashKey, String value) {
HashOperations<String, Object, Object> operation = null;
operation = template.opsForHash();
operation.put(key, hashKey, value);
}
/**
* 移除集合中一个或多个成员
*
* @param key
* @param values
* @return
*/
public long remove(String key, Object... values) {
SetOperations<String, Object> operation = null;
operation = template.opsForSet();
return operation.remove(key, values);
}
/**
* 判断 member 元素是否是集合 key 的成员
*
* @param key
* @param object
* @return
*/
public boolean isMember(String key, Object object) {
SetOperations<String, Object> operation = null;
operation = template.opsForSet();
return operation.isMember(key, object);
}
/**
* 返回集合中的所有成员
*
* @param key
* @return
*/
public Set<Object> members(String key) {
SetOperations<String, Object> operation = null;
operation = template.opsForSet();
return operation.members(key);
}
/**
* 随机获取key无序集合中的一个元素
*
* @param key
* @return
*/
public Object randomMember(String key) {
SetOperations<String, Object> operation = null;
operation = template.opsForSet();
return operation.randomMember(key);
}
/**
* 获取多个key无序集合中的元素(去重),count表示个数
*
* @param key
* @param count
* @return
*/
public Set<Object> distinctRandomMembers(String key, long count) {
SetOperations<String, Object> operation = null;
operation = template.opsForSet();
return operation.distinctRandomMembers(key, count);
}
/**
* 获取多个key无序集合中的元素,count表示个数
*
* @param key
* @param count
* @return
*/
public List<Object> randomMembers(String key, long count) {
SetOperations<String, Object> operation = null;
operation = template.opsForSet();
return operation.randomMembers(key, count);
}
/**
* 遍历zset
*
* @param key
* @param options
* @return
*/
Vector<Object> scan(String key, ScanOptions options) {
Vector<Object> array = null;
array = new Vector<Object>();
SetOperations<String, Object> operation = null;
operation = template.opsForSet();
Cursor<Object> cursor = null;
cursor = operation.scan(key, ScanOptions.NONE);
while (cursor.hasNext()) {
array.add(cursor.next());
}
return array;
}
/**
* redis性能读写测试 4000并发 1次操作
*
* @param args
*/
public synchronized static void main(String[] args) {
JedisUtils jedis = new JedisUtils();
System.out.println(jedis.getKey("123"));
long threadCount = 4000;// 并发
long excute = 10;// 执行次数
ExecutorService threadPool = Executors.newCachedThreadPool();
jedis.flushDB();
long startTime = System.currentTimeMillis();
for (int i = 0; i < threadCount; i++) {
threadPool.execute(new Runnable() { // 非线程安全
@Override
public void run() {
for (int j = 0; j < excute; j++) {
R.debug(jedis.setKey(R.getNano(), R.getNano()));
}
}
});
}
R.debug("excute method time is " + (System.currentTimeMillis() - startTime) / 1000);
threadPool.shutdown();
}
}