轉載自:https://github.com/whvcse/RedisUtil
代碼
ProtoStuffSerializerUtil.java
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.ProtostuffIOUtil;
import com.dyuproject.protostuff.Schema;
import com.dyuproject.protostuff.runtime.RuntimeSchema;
/**
* ProtoStuffSerializerUtil
*
* @author Sirius
* @date 2019-1-8
*/
public class ProtoStuffSerializerUtil {
/**
* 序列化對象
* @param obj
* @return
*/
public static <T> byte[] serialize(T obj) {
if (obj == null) {
throw new RuntimeException("序列化對象(" + obj + ")!");
}
@SuppressWarnings("unchecked")
Schema<T> schema = (Schema<T>) RuntimeSchema.getSchema(obj.getClass());
LinkedBuffer buffer = LinkedBuffer.allocate(1024 * 1024);
byte[] protostuff = null;
try {
protostuff = ProtostuffIOUtil.toByteArray(obj, schema, buffer);
} catch (Exception e) {
throw new RuntimeException("序列化(" + obj.getClass() + ")對象(" + obj + ")發生異常!", e);
} finally {
buffer.clear();
}
return protostuff;
}
/**
* 反序列化對象
* @param paramArrayOfByte
* @param targetClass
* @return
*/
public static <T> T deserialize(byte[] paramArrayOfByte, Class<T> targetClass) {
if (paramArrayOfByte == null || paramArrayOfByte.length == 0) {
throw new RuntimeException("反序列化對象發生異常,byte序列為空!");
}
T instance = null;
try {
instance = targetClass.newInstance();
} catch (InstantiationException e1) {
throw new RuntimeException("反序列化過程中依據類型創建對象失敗!", e1);
} catch(IllegalAccessException e2){
throw new RuntimeException("反序列化過程中依據類型創建對象失敗!", e2);
}
Schema<T> schema = RuntimeSchema.getSchema(targetClass);
ProtostuffIOUtil.mergeFrom(paramArrayOfByte, instance, schema);
return instance;
}
/**
* 序列化列表
* @param objList
* @return
*/
public static <T> byte[] serializeList(List<T> objList) {
if (objList == null || objList.isEmpty()) {
throw new RuntimeException("序列化對象列表(" + objList + ")參數異常!");
}
@SuppressWarnings("unchecked")
Schema<T> schema = (Schema<T>) RuntimeSchema.getSchema(objList.get(0).getClass());
LinkedBuffer buffer = LinkedBuffer.allocate(1024 * 1024);
byte[] protostuff = null;
ByteArrayOutputStream bos = null;
try {
bos = new ByteArrayOutputStream();
ProtostuffIOUtil.writeListTo(bos, objList, schema, buffer);
protostuff = bos.toByteArray();
} catch (Exception e) {
throw new RuntimeException("序列化對象列表(" + objList + ")發生異常!", e);
} finally {
buffer.clear();
try {
if (bos != null) {
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return protostuff;
}
/**
* 反序列化列表
* @param paramArrayOfByte
* @param targetClass
* @return
*/
public static <T> List<T> deserializeList(byte[] paramArrayOfByte, Class<T> targetClass) {
if (paramArrayOfByte == null || paramArrayOfByte.length == 0) {
throw new RuntimeException("反序列化對象發生異常,byte序列為空!");
}
Schema<T> schema = RuntimeSchema.getSchema(targetClass);
List<T> result = null;
try {
result = ProtostuffIOUtil.parseListFrom(new ByteArrayInputStream(paramArrayOfByte), schema);
} catch (IOException e) {
throw new RuntimeException("反序列化對象列表發生異常!", e);
}
return result;
}
}
RedisUtil.java
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Redis工具類
*
* @author WangFan
* @date 2018-02-24 下午03:09:50
* @version 1.1 (GitHub文檔: https://github.com/whvcse/RedisUtil )
*/
public class RedisUtil {
private StringRedisTemplate redisTemplate;
public void setRedisTemplate(StringRedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
public StringRedisTemplate getRedisTemplate() {
return this.redisTemplate;
}
/** -------------------key相關操作--------------------- */
/**
* 刪除key
*
* @param key
*/
public void delete(String key) {
redisTemplate.delete(key);
}
/**
* 批量刪除key
*
* @param keys
*/
public void delete(Collection<String> keys) {
redisTemplate.delete(keys);
}
/**
* 序列化key
*
* @param key
* @return
*/
public byte[] dump(String key) {
return redisTemplate.dump(key);
}
/**
* 是否存在key
*
* @param key
* @return
*/
public Boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* 設置過期時間
*
* @param key
* @param timeout
* @param unit
* @return
*/
public Boolean expire(String key, long timeout, TimeUnit unit) {
return redisTemplate.expire(key, timeout, unit);
}
/**
* 設置過期時間
*
* @param key
* @param date
* @return
*/
public Boolean expireAt(String key, Date date) {
return redisTemplate.expireAt(key, date);
}
/**
* 查找匹配的key
*
* @param pattern
* @return
*/
public Set<String> keys(String pattern) {
return redisTemplate.keys(pattern);
}
/**
* 將當前數據庫的 key 移動到給定的數據庫 db 當中
*
* @param key
* @param dbIndex
* @return
*/
public Boolean move(String key, int dbIndex) {
return redisTemplate.move(key, dbIndex);
}
/**
* 移除 key 的過期時間,key 將持久保持
*
* @param key
* @return
*/
public Boolean persist(String key) {
return redisTemplate.persist(key);
}
/**
* 返回 key 的剩余的過期時間
*
* @param key
* @param unit
* @return
*/
public Long getExpire(String key, TimeUnit unit) {
return redisTemplate.getExpire(key, unit);
}
/**
* 返回 key 的剩余的過期時間
*
* @param key
* @return
*/
public Long getExpire(String key) {
return redisTemplate.getExpire(key);
}
/**
* 從當前數據庫中隨機返回一個 key
*
* @return
*/
public String randomKey() {
return redisTemplate.randomKey();
}
/**
* 修改 key 的名稱
*
* @param oldKey
* @param newKey
*/
public void rename(String oldKey, String newKey) {
redisTemplate.rename(oldKey, newKey);
}
/**
* 僅當 newkey 不存在時,將 oldKey 改名為 newkey
*
* @param oldKey
* @param newKey
* @return
*/
public Boolean renameIfAbsent(String oldKey, String newKey) {
return redisTemplate.renameIfAbsent(oldKey, newKey);
}
/**
* 返回 key 所儲存的值的類型
*
* @param key
* @return
*/
public DataType type(String key) {
return redisTemplate.type(key);
}
/** -------------------string相關操作--------------------- */
/**
* 設置指定 key 的值
* @param key
* @param value
*/
public void set(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 獲取指定 key 的值
* @param key
* @return
*/
public String get(String key) {
return redisTemplate.opsForValue().get(key);
}
/**
* 返回 key 中字符串值的子字符
* @param key
* @param start
* @param end
* @return
*/
public String getRange(String key, long start, long end) {
return redisTemplate.opsForValue().get(key, start, end);
}
/**
* 將給定 key 的值設為 value ,並返回 key 的舊值(old value)
*
* @param key
* @param value
* @return
*/
public String getAndSet(String key, String value) {
return redisTemplate.opsForValue().getAndSet(key, value);
}
/**
* 對 key 所儲存的字符串值,獲取指定偏移量上的位(bit)
*
* @param key
* @param offset
* @return
*/
public Boolean getBit(String key, long offset) {
return redisTemplate.opsForValue().getBit(key, offset);
}
/**
* 批量獲取
*
* @param keys
* @return
*/
public List<String> multiGet(Collection<String> keys) {
return redisTemplate.opsForValue().multiGet(keys);
}
/**
* 設置ASCII碼, 字符串'a'的ASCII碼是97, 轉為二進制是'01100001', 此方法是將二進制第offset位值變為value
*
* @param key
* @param postion
* 位置
* @param value
* 值,true為1, false為0
* @return
*/
public boolean setBit(String key, long offset, boolean value) {
return redisTemplate.opsForValue().setBit(key, offset, value);
}
/**
* 將值 value 關聯到 key ,並將 key 的過期時間設為 timeout
*
* @param key
* @param value
* @param timeout
* 過期時間
* @param unit
* 時間單位, 天:TimeUnit.DAYS 小時:TimeUnit.HOURS 分鍾:TimeUnit.MINUTES
* 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS
*/
public void setEx(String key, String value, long timeout, TimeUnit unit) {
redisTemplate.opsForValue().set(key, value, timeout, unit);
}
/**
* 只有在 key 不存在時設置 key 的值
*
* @param key
* @param value
* @return 之前已經存在返回false,不存在返回true
*/
public boolean setIfAbsent(String key, String value) {
return redisTemplate.opsForValue().setIfAbsent(key, value);
}
/**
* 用 value 參數覆寫給定 key 所儲存的字符串值,從偏移量 offset 開始
*
* @param key
* @param value
* @param offset
* 從指定位置開始覆寫
*/
public void setRange(String key, String value, long offset) {
redisTemplate.opsForValue().set(key, value, offset);
}
/**
* 獲取字符串的長度
*
* @param key
* @return
*/
public Long size(String key) {
return redisTemplate.opsForValue().size(key);
}
/**
* 批量添加
*
* @param maps
*/
public void multiSet(Map<String, String> maps) {
redisTemplate.opsForValue().multiSet(maps);
}
/**
* 同時設置一個或多個 key-value 對,當且僅當所有給定 key 都不存在
*
* @param maps
* @return 之前已經存在返回false,不存在返回true
*/
public boolean multiSetIfAbsent(Map<String, String> maps) {
return redisTemplate.opsForValue().multiSetIfAbsent(maps);
}
/**
* 增加(自增長), 負數則為自減
*
* @param key
* @param value
* @return
*/
public Long incrBy(String key, long increment) {
return redisTemplate.opsForValue().increment(key, increment);
}
/**
*
* @param key
* @param value
* @return
*/
public Double incrByFloat(String key, double increment) {
return redisTemplate.opsForValue().increment(key, increment);
}
/**
* 追加到末尾
*
* @param key
* @param value
* @return
*/
public Integer append(String key, String value) {
return redisTemplate.opsForValue().append(key, value);
}
/** -------------------hash相關操作------------------------- */
/**
* 獲取存儲在哈希表中指定字段的值
*
* @param key
* @param field
* @return
*/
public Object hGet(String key, String field) {
return redisTemplate.opsForHash().get(key, field);
}
/**
* 獲取所有給定字段的值
*
* @param key
* @return
*/
public Map<Object, Object> hGetAll(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* 獲取所有給定字段的值
*
* @param key
* @param fields
* @return
*/
public List<Object> hMultiGet(String key, Collection<Object> fields) {
return redisTemplate.opsForHash().multiGet(key, fields);
}
public void hPut(String key, String hashKey, String value) {
redisTemplate.opsForHash().put(key, hashKey, value);
}
public void hPutAll(String key, Map<String, String> maps) {
redisTemplate.opsForHash().putAll(key, maps);
}
/**
* 僅當hashKey不存在時才設置
*
* @param key
* @param hashKey
* @param value
* @return
*/
public Boolean hPutIfAbsent(String key, String hashKey, String value) {
return redisTemplate.opsForHash().putIfAbsent(key, hashKey, value);
}
/**
* 刪除一個或多個哈希表字段
*
* @param key
* @param fields
* @return
*/
public Long hDelete(String key, Object... fields) {
return redisTemplate.opsForHash().delete(key, fields);
}
/**
* 查看哈希表 key 中,指定的字段是否存在
*
* @param key
* @param field
* @return
*/
public boolean hExists(String key, String field) {
return redisTemplate.opsForHash().hasKey(key, field);
}
/**
* 為哈希表 key 中的指定字段的整數值加上增量 increment
*
* @param key
* @param field
* @param increment
* @return
*/
public Long hIncrBy(String key, Object field, long increment) {
return redisTemplate.opsForHash().increment(key, field, increment);
}
/**
* 為哈希表 key 中的指定字段的整數值加上增量 increment
*
* @param key
* @param field
* @param delta
* @return
*/
public Double hIncrByFloat(String key, Object field, double delta) {
return redisTemplate.opsForHash().increment(key, field, delta);
}
/**
* 獲取所有哈希表中的字段
*
* @param key
* @return
*/
public Set<Object> hKeys(String key) {
return redisTemplate.opsForHash().keys(key);
}
/**
* 獲取哈希表中字段的數量
*
* @param key
* @return
*/
public Long hSize(String key) {
return redisTemplate.opsForHash().size(key);
}
/**
* 獲取哈希表中所有值
*
* @param key
* @return
*/
public List<Object> hValues(String key) {
return redisTemplate.opsForHash().values(key);
}
/**
* 迭代哈希表中的鍵值對
*
* @param key
* @param options
* @return
*/
public Cursor<Entry<Object, Object>> hScan(String key, ScanOptions options) {
return redisTemplate.opsForHash().scan(key, options);
}
/** ------------------------list相關操作---------------------------- */
/**
* 通過索引獲取列表中的元素
*
* @param key
* @param index
* @return
*/
public String lIndex(String key, long index) {
return redisTemplate.opsForList().index(key, index);
}
/**
* 獲取列表指定范圍內的元素
*
* @param key
* @param start
* 開始位置, 0是開始位置
* @param end
* 結束位置, -1返回所有
* @return
*/
public List<String> lRange(String key, long start, long end) {
return redisTemplate.opsForList().range(key, start, end);
}
/**
* 存儲在list頭部
*
* @param key
* @param value
* @return
*/
public Long lLeftPush(String key, String value) {
return redisTemplate.opsForList().leftPush(key, value);
}
/**
*
* @param key
* @param value
* @return
*/
public Long lLeftPushAll(String key, String... value) {
return redisTemplate.opsForList().leftPushAll(key, value);
}
/**
*
* @param key
* @param value
* @return
*/
public Long lLeftPushAll(String key, Collection<String> value) {
return redisTemplate.opsForList().leftPushAll(key, value);
}
/**
* 當list存在的時候才加入
*
* @param key
* @param value
* @return
*/
public Long lLeftPushIfPresent(String key, String value) {
return redisTemplate.opsForList().leftPushIfPresent(key, value);
}
/**
* 如果pivot存在,再pivot前面添加
*
* @param key
* @param pivot
* @param value
* @return
*/
public Long lLeftPush(String key, String pivot, String value) {
return redisTemplate.opsForList().leftPush(key, pivot, value);
}
/**
*
* @param key
* @param value
* @return
*/
public Long lRightPush(String key, String value) {
return redisTemplate.opsForList().rightPush(key, value);
}
/**
*
* @param key
* @param value
* @return
*/
public Long lRightPushAll(String key, String... value) {
return redisTemplate.opsForList().rightPushAll(key, value);
}
/**
*
* @param key
* @param value
* @return
*/
public Long lRightPushAll(String key, Collection<String> value) {
return redisTemplate.opsForList().rightPushAll(key, value);
}
/**
* 為已存在的列表添加值
*
* @param key
* @param value
* @return
*/
public Long lRightPushIfPresent(String key, String value) {
return redisTemplate.opsForList().rightPushIfPresent(key, value);
}
/**
* 在pivot元素的右邊添加值
*
* @param key
* @param pivot
* @param value
* @return
*/
public Long lRightPush(String key, String pivot, String value) {
return redisTemplate.opsForList().rightPush(key, pivot, value);
}
/**
* 通過索引設置列表元素的值
*
* @param key
* @param index
* 位置
* @param value
*/
public void lSet(String key, long index, String value) {
redisTemplate.opsForList().set(key, index, value);
}
/**
* 移出並獲取列表的第一個元素
*
* @param key
* @return 刪除的元素
*/
public String lLeftPop(String key) {
return redisTemplate.opsForList().leftPop(key);
}
/**
* 移出並獲取列表的第一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止
*
* @param key
* @param timeout
* 等待時間
* @param unit
* 時間單位
* @return
*/
public String lBLeftPop(String key, long timeout, TimeUnit unit) {
return redisTemplate.opsForList().leftPop(key, timeout, unit);
}
/**
* 移除並獲取列表最后一個元素
*
* @param key
* @return 刪除的元素
*/
public String lRightPop(String key) {
return redisTemplate.opsForList().rightPop(key);
}
/**
* 移出並獲取列表的最后一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止
*
* @param key
* @param timeout
* 等待時間
* @param unit
* 時間單位
* @return
*/
public String lBRightPop(String key, long timeout, TimeUnit unit) {
return redisTemplate.opsForList().rightPop(key, timeout, unit);
}
/**
* 移除列表的最后一個元素,並將該元素添加到另一個列表並返回
*
* @param sourceKey
* @param destinationKey
* @return
*/
public String lRightPopAndLeftPush(String sourceKey, String destinationKey) {
return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey,
destinationKey);
}
/**
* 從列表中彈出一個值,將彈出的元素插入到另外一個列表中並返回它; 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止
*
* @param sourceKey
* @param destinationKey
* @param timeout
* @param unit
* @return
*/
public String lBRightPopAndLeftPush(String sourceKey, String destinationKey,
long timeout, TimeUnit unit) {
return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey,
destinationKey, timeout, unit);
}
/**
* 刪除集合中值等於value得元素
*
* @param key
* @param index
* index=0, 刪除所有值等於value的元素; index>0, 從頭部開始刪除第一個值等於value的元素;
* index<0, 從尾部開始刪除第一個值等於value的元素;
* @param value
* @return
*/
public Long lRemove(String key, long index, String value) {
return redisTemplate.opsForList().remove(key, index, value);
}
/**
* 裁剪list
*
* @param key
* @param start
* @param end
*/
public void lTrim(String key, long start, long end) {
redisTemplate.opsForList().trim(key, start, end);
}
/**
* 獲取列表長度
*
* @param key
* @return
*/
public Long lLen(String key) {
return redisTemplate.opsForList().size(key);
}
/** --------------------set相關操作-------------------------- */
/**
* set添加元素
*
* @param key
* @param values
* @return
*/
public Long sAdd(String key, String... values) {
return redisTemplate.opsForSet().add(key, values);
}
/**
* set移除元素
*
* @param key
* @param values
* @return
*/
public Long sRemove(String key, Object... values) {
return redisTemplate.opsForSet().remove(key, values);
}
/**
* 移除並返回集合的一個隨機元素
*
* @param key
* @return
*/
public String sPop(String key) {
return redisTemplate.opsForSet().pop(key);
}
/**
* 將元素value從一個集合移到另一個集合
*
* @param key
* @param value
* @param destKey
* @return
*/
public Boolean sMove(String key, String value, String destKey) {
return redisTemplate.opsForSet().move(key, value, destKey);
}
/**
* 獲取集合的大小
*
* @param key
* @return
*/
public Long sSize(String key) {
return redisTemplate.opsForSet().size(key);
}
/**
* 判斷集合是否包含value
*
* @param key
* @param value
* @return
*/
public Boolean sIsMember(String key, Object value) {
return redisTemplate.opsForSet().isMember(key, value);
}
/**
* 獲取兩個集合的交集
*
* @param key
* @param otherKey
* @return
*/
public Set<String> sIntersect(String key, String otherKey) {
return redisTemplate.opsForSet().intersect(key, otherKey);
}
/**
* 獲取key集合與多個集合的交集
*
* @param key
* @param otherKeys
* @return
*/
public Set<String> sIntersect(String key, Collection<String> otherKeys) {
return redisTemplate.opsForSet().intersect(key, otherKeys);
}
/**
* key集合與otherKey集合的交集存儲到destKey集合中
*
* @param key
* @param otherKey
* @param destKey
* @return
*/
public Long sIntersectAndStore(String key, String otherKey, String destKey) {
return redisTemplate.opsForSet().intersectAndStore(key, otherKey,
destKey);
}
/**
* key集合與多個集合的交集存儲到destKey集合中
*
* @param key
* @param otherKeys
* @param destKey
* @return
*/
public Long sIntersectAndStore(String key, Collection<String> otherKeys,
String destKey) {
return redisTemplate.opsForSet().intersectAndStore(key, otherKeys,
destKey);
}
/**
* 獲取兩個集合的並集
*
* @param key
* @param otherKeys
* @return
*/
public Set<String> sUnion(String key, String otherKeys) {
return redisTemplate.opsForSet().union(key, otherKeys);
}
/**
* 獲取key集合與多個集合的並集
*
* @param key
* @param otherKeys
* @return
*/
public Set<String> sUnion(String key, Collection<String> otherKeys) {
return redisTemplate.opsForSet().union(key, otherKeys);
}
/**
* key集合與otherKey集合的並集存儲到destKey中
*
* @param key
* @param otherKey
* @param destKey
* @return
*/
public Long sUnionAndStore(String key, String otherKey, String destKey) {
return redisTemplate.opsForSet().unionAndStore(key, otherKey, destKey);
}
/**
* key集合與多個集合的並集存儲到destKey中
*
* @param key
* @param otherKeys
* @param destKey
* @return
*/
public Long sUnionAndStore(String key, Collection<String> otherKeys,
String destKey) {
return redisTemplate.opsForSet().unionAndStore(key, otherKeys, destKey);
}
/**
* 獲取兩個集合的差集
*
* @param key
* @param otherKey
* @return
*/
public Set<String> sDifference(String key, String otherKey) {
return redisTemplate.opsForSet().difference(key, otherKey);
}
/**
* 獲取key集合與多個集合的差集
*
* @param key
* @param otherKeys
* @return
*/
public Set<String> sDifference(String key, Collection<String> otherKeys) {
return redisTemplate.opsForSet().difference(key, otherKeys);
}
/**
* key集合與otherKey集合的差集存儲到destKey中
*
* @param key
* @param otherKey
* @param destKey
* @return
*/
public Long sDifference(String key, String otherKey, String destKey) {
return redisTemplate.opsForSet().differenceAndStore(key, otherKey,
destKey);
}
/**
* key集合與多個集合的差集存儲到destKey中
*
* @param key
* @param otherKeys
* @param destKey
* @return
*/
public Long sDifference(String key, Collection<String> otherKeys,
String destKey) {
return redisTemplate.opsForSet().differenceAndStore(key, otherKeys,
destKey);
}
/**
* 獲取集合所有元素
*
* @param key
* @param otherKeys
* @param destKey
* @return
*/
public Set<String> setMembers(String key) {
return redisTemplate.opsForSet().members(key);
}
/**
* 隨機獲取集合中的一個元素
*
* @param key
* @return
*/
public String sRandomMember(String key) {
return redisTemplate.opsForSet().randomMember(key);
}
/**
* 隨機獲取集合中count個元素
*
* @param key
* @param count
* @return
*/
public List<String> sRandomMembers(String key, long count) {
return redisTemplate.opsForSet().randomMembers(key, count);
}
/**
* 隨機獲取集合中count個元素並且去除重復的
*
* @param key
* @param count
* @return
*/
public Set<String> sDistinctRandomMembers(String key, long count) {
return redisTemplate.opsForSet().distinctRandomMembers(key, count);
}
/**
*
* @param key
* @param options
* @return
*/
public Cursor<String> sScan(String key, ScanOptions options) {
return redisTemplate.opsForSet().scan(key, options);
}
/**------------------zSet相關操作--------------------------------*/
/**
* 添加元素,有序集合是按照元素的score值由小到大排列
*
* @param key
* @param value
* @param score
* @return
*/
public Boolean zAdd(String key, String value, double score) {
return redisTemplate.opsForZSet().add(key, value, score);
}
/**
*
* @param key
* @param values
* @return
*/
public Long zAdd(String key, Set<TypedTuple<String>> values) {
return redisTemplate.opsForZSet().add(key, values);
}
/**
*
* @param key
* @param values
* @return
*/
public Long zRemove(String key, Object... values) {
return redisTemplate.opsForZSet().remove(key, values);
}
/**
* 增加元素的score值,並返回增加后的值
*
* @param key
* @param value
* @param delta
* @return
*/
public Double zIncrementScore(String key, String value, double delta) {
return redisTemplate.opsForZSet().incrementScore(key, value, delta);
}
/**
* 返回元素在集合的排名,有序集合是按照元素的score值由小到大排列
*
* @param key
* @param value
* @return 0表示第一位
*/
public Long zRank(String key, Object value) {
return redisTemplate.opsForZSet().rank(key, value);
}
/**
* 返回元素在集合的排名,按元素的score值由大到小排列
*
* @param key
* @param value
* @return
*/
public Long zReverseRank(String key, Object value) {
return redisTemplate.opsForZSet().reverseRank(key, value);
}
/**
* 獲取集合的元素, 從小到大排序
*
* @param key
* @param start
* 開始位置
* @param end
* 結束位置, -1查詢所有
* @return
*/
public Set<String> zRange(String key, long start, long end) {
return redisTemplate.opsForZSet().range(key, start, end);
}
/**
* 獲取集合元素, 並且把score值也獲取
*
* @param key
* @param start
* @param end
* @return
*/
public Set<TypedTuple<String>> zRangeWithScores(String key, long start,
long end) {
return redisTemplate.opsForZSet().rangeWithScores(key, start, end);
}
/**
* 根據Score值查詢集合元素
*
* @param key
* @param min
* 最小值
* @param max
* 最大值
* @return
*/
public Set<String> zRangeByScore(String key, double min, double max) {
return redisTemplate.opsForZSet().rangeByScore(key, min, max);
}
/**
* 根據Score值查詢集合元素, 從小到大排序
*
* @param key
* @param min
* 最小值
* @param max
* 最大值
* @return
*/
public Set<TypedTuple<String>> zRangeByScoreWithScores(String key,
double min, double max) {
return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max);
}
/**
*
* @param key
* @param min
* @param max
* @param start
* @param end
* @return
*/
public Set<TypedTuple<String>> zRangeByScoreWithScores(String key,
double min, double max, long start, long end) {
return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max,
start, end);
}
/**
* 獲取集合的元素, 從大到小排序
*
* @param key
* @param start
* @param end
* @return
*/
public Set<String> zReverseRange(String key, long start, long end) {
return redisTemplate.opsForZSet().reverseRange(key, start, end);
}
/**
* 獲取集合的元素, 從大到小排序, 並返回score值
*
* @param key
* @param start
* @param end
* @return
*/
public Set<TypedTuple<String>> zReverseRangeWithScores(String key,
long start, long end) {
return redisTemplate.opsForZSet().reverseRangeWithScores(key, start,
end);
}
/**
* 根據Score值查詢集合元素, 從大到小排序
*
* @param key
* @param min
* @param max
* @return
*/
public Set<String> zReverseRangeByScore(String key, double min,
double max) {
return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max);
}
/**
* 根據Score值查詢集合元素, 從大到小排序
*
* @param key
* @param min
* @param max
* @return
*/
public Set<TypedTuple<String>> zReverseRangeByScoreWithScores(
String key, double min, double max) {
return redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key,
min, max);
}
/**
*
* @param key
* @param min
* @param max
* @param start
* @param end
* @return
*/
public Set<String> zReverseRangeByScore(String key, double min,
double max, long start, long end) {
return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max,
start, end);
}
/**
* 根據score值獲取集合元素數量
*
* @param key
* @param min
* @param max
* @return
*/
public Long zCount(String key, double min, double max) {
return redisTemplate.opsForZSet().count(key, min, max);
}
/**
* 獲取集合大小
*
* @param key
* @return
*/
public Long zSize(String key) {
return redisTemplate.opsForZSet().size(key);
}
/**
* 獲取集合大小
*
* @param key
* @return
*/
public Long zZCard(String key) {
return redisTemplate.opsForZSet().zCard(key);
}
/**
* 獲取集合中value元素的score值
*
* @param key
* @param value
* @return
*/
public Double zScore(String key, Object value) {
return redisTemplate.opsForZSet().score(key, value);
}
/**
* 移除指定索引位置的成員
*
* @param key
* @param start
* @param end
* @return
*/
public Long zRemoveRange(String key, long start, long end) {
return redisTemplate.opsForZSet().removeRange(key, start, end);
}
/**
* 根據指定的score值的范圍來移除成員
*
* @param key
* @param min
* @param max
* @return
*/
public Long zRemoveRangeByScore(String key, double min, double max) {
return redisTemplate.opsForZSet().removeRangeByScore(key, min, max);
}
/**
* 獲取key和otherKey的並集並存儲在destKey中
*
* @param key
* @param otherKey
* @param destKey
* @return
*/
public Long zUnionAndStore(String key, String otherKey, String destKey) {
return redisTemplate.opsForZSet().unionAndStore(key, otherKey, destKey);
}
/**
*
* @param key
* @param otherKeys
* @param destKey
* @return
*/
public Long zUnionAndStore(String key, Collection<String> otherKeys,
String destKey) {
return redisTemplate.opsForZSet()
.unionAndStore(key, otherKeys, destKey);
}
/**
* 交集
*
* @param key
* @param otherKey
* @param destKey
* @return
*/
public Long zIntersectAndStore(String key, String otherKey,
String destKey) {
return redisTemplate.opsForZSet().intersectAndStore(key, otherKey,
destKey);
}
/**
* 交集
*
* @param key
* @param otherKeys
* @param destKey
* @return
*/
public Long zIntersectAndStore(String key, Collection<String> otherKeys,
String destKey) {
return redisTemplate.opsForZSet().intersectAndStore(key, otherKeys,
destKey);
}
/**
*
* @param key
* @param options
* @return
*/
public Cursor<TypedTuple<String>> zScan(String key, ScanOptions options) {
return redisTemplate.opsForZSet().scan(key, options);
}
/**
* 獲取Redis List 序列化
* @param key
* @param targetClass
* @param <T>
* @return
*/
public <T> List<T> getListCache(final String key, Class<T> targetClass) {
byte[] result = redisTemplate.execute(new RedisCallback<byte[]>() {
@Override
public byte[] doInRedis(RedisConnection connection) throws DataAccessException {
return connection.get(key.getBytes());
}
});
if (result == null) {
return null;
}
return ProtoStuffSerializerUtil.deserializeList(result, targetClass);
}
/***
* 將List 放進緩存里面
* @param key
* @param objList
* @param expireTime
* @param <T>
* @return
*/
public <T> boolean putListCacheWithExpireTime(String key, List<T> objList, final long expireTime) {
final byte[] bkey = key.getBytes();
final byte[] bvalue = ProtoStuffSerializerUtil.serializeList(objList);
boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
connection.setEx(bkey, expireTime, bvalue);
return true;
}
});
return result;
}
}
用法
最全的Java操作Redis的工具類,封裝了對Redis五種基本類型的各種操作,力求符合Redis的原生操作,使用StringRedisTemplate實現!
keys相關命令
NO | 方法 | 描述 |
---|---|---|
1 | void delete(String key) | key存在時刪除key |
2 | void delete(Collection keys) | 批量刪除key |
3 | byte[] dump(String key) | 序列化key,返回被序列化的值 |
4 | Boolean hasKey(String key) | 檢查key是否存在 |
5 | Boolean expire(String key, long timeout, TimeUnit unit) | 設置過期時間 |
6 | Boolean expireAt(String key, Date date) | 設置過期時間 |
7 | Set
|
查找所有符合給定模式(pattern)的key |
8 | Boolean move(String key, int dbIndex) | 將當前數據庫的key移動到給定的數據庫db當中 |
9 | Boolean persist(String key) | 移除key的過期時間,key將持久保持 |
10 | Long getExpire(String key, TimeUnit unit) | 返回key的剩余的過期時間 |
11 | Long getExpire(String key) | 返回key的剩余的過期時間 |
12 | String randomKey() | 從當前數據庫中隨機返回一個key |
13 | void rename(String oldKey, String newKey) | 修改key的名稱 |
14 | Boolean renameIfAbsent(String oldKey, String newKey) | 僅當newkey不存在時,將oldKey改名為 newkey |
15 | DataType type(String key) | 返回key所儲存的值的類型 |
TimeUnit是時間單位,可選值有:
天:TimeUnit.DAYS、小時:TimeUnit.HOURS、分鍾:TimeUnit.MINUTES、秒:TimeUnit.SECONDS、毫秒:TimeUnit.MILLISECONDS。
String數據類型操作
NO | 方法 | 描述 |
---|---|---|
1 | String get(String key) | 獲取指定key的值 |
2 | String getRange(String key, long start, long end) | 返回key中字符串值的子字符 |
3 | String getAndSet(String key, String value) | 將key的值設為value,並返回key舊值 |
4 | Boolean getBit(String key, long offset) | 對key所儲存的值,獲取指定位置上的bit |
5 | List multiGet(Collection keys) | 批量獲取 |
添加相關 | ||
6 | void set(String key, String value) | 設置指定key的值 |
7 | boolean setBit(String key, long offset, boolean value) | 設置指定位置上的ASCII碼 |
8 | void setEx(String key,String value,long timeout,TimeUnit unit) | 將值value關聯到key,並設置key過期時間 |
9 | boolean setIfAbsent(String key, String value) | 只有在 key 不存在時設置 key 的值 |
10 | void setRange(String key, String value, long offset) | 用value覆寫key的值,從偏移量offset開始 |
11 | void multiSet(Map<String,String> maps) | 批量添加 |
12 | boolean multiSetIfAbsent(Map<String,String> maps) | 批量添加,僅當所有key都不存在 |
其他方法 | ||
13 | Integer append(String key, String value) | 追加到末尾 |
14 | Long incrBy(String key, long increment) | 增加(自增長), 負數則為自減 |
15 | Double incrByFloat(String key, double increment) | 增加(自增長), 負數則為自減 |
16 | Long size(String key) | 獲取字符串的長度 |
關於上面xxBit方法的使用:
例如字符'a'的ASCII碼是97,轉為二進制是'01100001',setBit方法就是把第offset位置上變成0或者1,true是1,false是0。
Hash相關的操作
NO | 方法 | 描述 |
---|---|---|
1 | Object hGet(String key, String field) | 獲取存儲在哈希表中指定字段的值 |
2 | Map hGetAll(String key) | 獲取所有給定字段的值 |
3 | List hMultiGet(String key, Collection fields) | 獲取所有給定字段的值 |
添加相關 | ||
4 | void hPut(String key, String hashKey, String value) | 添加字段 |
5 | void hPutAll(String key, Map maps) | 添加多個字段 |
6 | Boolean hPutIfAbsent(String key,String hashKey,String value) | 僅當hashKey不存在時才設置 |
其他方法 | ||
7 | Long hDelete(String key, Object... fields) | 刪除一個或多個哈希表字段 |
8 | boolean hExists(String key, String field) | 查看哈希表key中指定的字段是否存在 |
9 | Long hIncrBy(String key, Object field, long increment) | 為哈希表key中指定字段的值增加increment |
10 | Double hIncrByFloat(String key, Object field, double delta) | 為哈希表key中指定字段的值增加increment |
11 | Set hKeys(String key) | 獲取所有哈希表中的字段 |
12 | Long hSize(String key) | 獲取哈希表中字段的數量 |
13 | List hValues(String key) | 獲取哈希表中所有值 |
14 | Cursor hScan(String key, ScanOptions options) | 迭代哈希表中的鍵值對 |
引入序列化依賴 |
|
|
15 | getListCache(final String key, Class
|
獲取緩存中的List,targetClass是序列化的類 |
16 | putListCacheWithExpireTime(String key, List
|
把List放到緩存,expireTime是過期策略 |
List相關的操作
NO | 方法 | 描述 |
---|---|---|
1 | String lIndex(String key, long index) | 通過索引獲取列表中的元素 |
2 | List lRange(String key, long start, long end) | 獲取列表指定范圍內的元素 |
添加相關 | ||
3 | Long lLeftPush(String key, String value) | 存儲在list頭部 |
4 | Long lLeftPushAll(String key, String... value) | 存儲在list頭部 |
5 | Long lLeftPushAll(String key, Collection value) | 存儲在list頭部 |
6 | Long lLeftPushIfPresent(String key, String value) | 當list存在的時候才加入 |
7 | lLeftPush(String key, String pivot, String value) | 如果pivot存在,再pivot前面添加 |
8 | Long lRightPush(String key, String value) | 存儲在list尾部 |
9 | Long lRightPushAll(String key, String... value) | 存儲在list尾部 |
10 | Long lRightPushAll(String key, Collection value) | 存儲在list尾部 |
11 | Long lRightPushIfPresent(String key, String value) | 當list存在的時候才加入 |
12 | lRightPush(String key, String pivot, String value) | 在pivot元素的右邊添加值 |
13 | void lSet(String key, long index, String value) | 通過索引設置列表元素的值 |
刪除相關 | ||
14 | String lLeftPop(String key) | 移出並獲取列表的第一個元素 |
15 | String lBLeftPop(String key,long timeout,TimeUnit unit) | 移出並獲取第一個元素,沒有則阻塞直到超時或有為止 |
16 | String lRightPop(String key) | 移除並獲取列表最后一個元素 |
17 | String lBRightPop(String key,long timeout,TimeUnit unit) | 移出並獲取最后個元素,沒有則阻塞直到超時或有為止 |
18 | String lRightPopAndLeftPush(String sKey,String dKey) | 移除最后一個元素並加到另一個列表並返回 |
19 | String lBRightPopAndLeftPush(sKey,dKey,timeout,unit) | 移除最后個元素並加到另個列表並返回,阻塞超時或有 |
20 | Long lRemove(String key, long index, String value) | 刪除集合中值等於value得元素 |
21 | void lTrim(String key, long start, long end) | 裁剪list |
其他方法 | ||
22 | Long lLen(String key) | 獲取列表長度 |
Set相關的操作
NO | 方法 | 描述 |
---|---|---|
1 | Set
|
獲取集合所有元素 |
2 | Long sSize(String key) | 獲取集合大小 |
3 | Boolean sIsMember(String key, Object value) | 判斷集合是否包含value |
4 | String sRandomMember(String key) | 隨機獲取集合中的一個元素 |
5 | List
|
隨機獲取集合count個元素 |
6 | Set
|
隨機獲取count個元素並去除重復的 |
7 | Cursor
|
使用迭代器獲取元素 |
8 | Set
|
獲取兩個集合的交集 |
9 | Set
|
獲取key集合與多個集合的交集 |
10 | Long sIntersectAndStore(String key, String oKey, String dKey) | key集合與oKey的交集存儲到dKey中 |
11 | Long sIntersectAndStore(String key,Collection
|
key與多個集合的交集存儲到dKey中 |
12 | Set
|
獲取兩個集合的並集 |
13 | Set
|
獲取key集合與多個集合的並集 |
14 | Long sUnionAndStore(String key, String otherKey, String destKey) | key集合與oKey的並集存儲到dKey中 |
15 | Long sUnionAndStore(String key,Collection
|
key與多個集合的並集存儲到dKey中 |
16 | Set
|
獲取兩個集合的差集 |
17 | Set
|
獲取key集合與多個集合的差集 |
18 | Long sDifference(String key, String otherKey, String destKey) | key與oKey集合的差集存儲到dKey中 |
19 | Long sDifference(String key,Collection
|
key與多個集合的差集存儲到dKey中 |
添加相關 | ||
20 | Long sAdd(String key, String... values) | 添加 |
刪除相關 | ||
21 | Long sRemove(String key, Object... values) | 移除 |
22 | String sPop(String key) | 隨機移除一個元素 |
23 | Boolean sMove(String key, String value, String destKey) | 將key集合中value移到destKey中 |
zset數據類型操作
NO | 方法 | 描述 |
---|---|---|
1 | Set
|
獲取元素,小到大排序,s開始e結束位置 |
2 | Set<TypedTuple
|
獲取集合元素, 並且把score值也獲取 |
3 | Set
|
根據score范圍查詢元素,從小到大排序 |
4 | Set<TypedTuple
|
根據score范圍查詢元素,並返回score |
5 | Set
|
根據score查詢元素,s開始e結束位置 |
6 | Set
|
獲取集合元素, 從大到小排序 |
7 | Set<TypedTuple
|
獲取元素,從大到小排序,並返回score |
8 | Set
|
根據score范圍查詢元素,從大到小排序 |
9 | Set
|
根據score查詢,大到小排序返回score |
10 | Set
|
根據score查詢,大到小,s開始e結束 |
11 | Long zRank(String key, Object value) | 返回元素在集合的排名,score由小到大 |
12 | Long zReverseRank(String key, Object value) | 返回元素在集合的排名,score由大到小 |
13 | Long zCount(String key, double min, double max) | 根據score值范圍獲取集合元素的數量 |
14 | Long zSize(String key) | 獲取集合大小 |
15 | Long zZCard(String key) | 獲取集合大小 |
16 | Double zScore(String key, Object value) | 獲取集合中value元素的score值 |
17 | Long zUnionAndStore(String key, String otherKey, String destKey) | 獲取key和oKey的並集並存儲在dKey中 |
18 | Long zUnionAndStore(String key,Collection
|
獲取key和多個集合並集並存在dKey中 |
19 | Long zIntersectAndStore(String key, String otherKey, String destKey) | 獲取key和oKey交集並存在destKey中 |
20 | Long zIntersectAndStore(String key,Collection
|
獲取key和多個集合交集並存在dKey中 |
21 | Cursor<TypedTuple
|
使用迭代器獲取 |
添加相關 | ||
22 | Boolean zAdd(String key, String value, double score) | 添加元素,zSet按score由小到大排列 |
23 | Long zAdd(String key, Set<TypedTuple
|
批量添加,TypedTuple使用見下面介紹 |
刪除相關 | ||
24 | Long zRemove(String key, Object... values) | 移除 |
25 | Double zIncrementScore(String key, String value, double delta) | 增加元素的score值,並返回增加后的值 |
26 | Long zRemoveRange(String key, long start, long end) | 移除指定索引位置的成員 |
27 | Long zRemoveRangeByScore(String key, double min, double max) | 根據指定的score值的范圍來移除成員 |
批量添加時
TypedTuple
的使用:
TypedTupletypedTuple = new DefaultTypedTuple (value,score)
知識補充
Redis知識補充
Redis 可以存儲鍵與5種不同數據結構類型之間的映射,這5種數據結構類型分別為:String(字符串)、List(列表)、Set(集合)、Hash(散列)和 zSet(有序集合)。
String(字符串)
結構存儲的值:
可以是字符串、整數或者浮點數。
結構的讀寫能力:
對整個字符串或者字符串的其中一部分執行操作,對象和浮點數執行自增(increment)或者自減(decrement)。
List(列表)
結構存儲的值:
一個鏈表,鏈表上的每個節點都包含了一個字符串。
結構的讀寫能力:
從鏈表的兩端推入或者彈出元素,根據偏移量(offset)對鏈表進行修剪(trim),讀取單個或者多個元素,根據值來查找或者移除元素。
Set(集合)
結構存儲的值:
包含字符串的無序收集器(unOrderedCollection),並且被包含的每個字符串都是獨一無二的、各不相同。
結構的讀寫能力:
添加、獲取、移除單個元素,檢查一個元素是否存在於某個集合中,計算交集、並集、差集,從集合里面隨機獲取元素。
Hash(散列)
結構存儲的值:
包含鍵值對的無序散列表。
結構的讀寫能力:
添加、獲取、移除單個鍵值對,獲取所有鍵值對。
zSet(有序集合)
結構存儲的值:
字符串成員(member)與浮點數分值(score)之間的有序映射,元素的排列順序由分值(score)的大小決定。
結構的讀寫能力:
添加、獲取、刪除單個元素,根據分值(score)范圍(range)或者成員來獲取元素。
RedisTemplate和StringRedisTemplate
二者主要區別是他們使用的序列化類不一樣,RedisTemplate使用的是JdkSerializationRedisSerializer,
StringRedisTemplate使用的是StringRedisSerializer,兩者的數據是不共通的。
1RedisTemplate:
RedisTemplate使用的是JDK的序列化策略,向Redis存入數據會將數據先序列化成字節數組然后在存入Redis數據庫,
這個時候打開Redis查看的時候,你會看到你的數據不是以可讀的形式展現的,而是以字節數組顯示,類似下面:\xAC\xED\x00\x05t\x05sr\x00
。
所以使用RedisTemplate可以把一個Java對象直接存儲在Redis里面,但是存進去的數據是不易直觀讀的,不通用的,
建議不要直接存一個Object對象,可以變成Hash來存儲,也可以轉成json格式的數據來存儲,在實際應用中也是很多都采用json格式來存儲的。
2StringRedisTemplate:
StringRedisTemplate默認采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的,
StringRedisTemplate是繼承RedisTemplate的,這種對redis的操方式更優雅,任何Redis連接工具,都可以讀出直觀的數據,便於數據的維護。
Redis與Spring的集成
1.集成配置
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="300" />
<property name="maxTotal" value="600" />
<property name="maxWaitMillis" value="1000" />
<property name="testOnBorrow" value="true" />
</bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="127.0.0.1" />
<property name="password" value="" />
<property name="port" value="6379" />
<property name="poolConfig" ref="poolConfig" />
</bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
</bean>
<!-- RedisUtil注入RedisTemplate -->
<bean id="redisUtil" class="com.xxx.utils.RedisUtil">
<property name="redisTemplate" ref="redisTemplate" />
</bean>
2.使用RedisUtil工具類方法如下:
@Autowired
private RedisUtil redisUtil;
SpringBoot中如何使用
maven依賴:
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>1.0.8</version>
</dependency>
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>1.0.8</version>
</dependency>
<!--springboot中的redis依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
修改你的RedisUtil代碼:
@Component
public class RedisUtil {
@Autowired
private StringRedisTemplate redisTemplate;
......
}
使用@Autowired
自動注入redisTemplate。