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(); } }