Commit a3f88966 by qiuweili123

add redis

parent ba6d6374
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>matrix-datahelper</artifactId>
<groupId>com.secoo.mall</groupId>
<version>1.3.2.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>matrix-datahelper-redis-core</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>common-util</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.secoo.mall.redis.template;
import com.secoo.mall.common.util.colletion.CollectionUtil;
import com.secoo.mall.common.util.string.StringUtil;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
import org.springframework.data.redis.connection.jedis.JedisClusterConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.serializer.RedisSerializer;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class MatrixRedisTemplate {
private RedisTemplate<String, ?> redisTemplate;
public RedisTemplate<String, ?> getRedisTemplate() {
return redisTemplate;
}
public void setRedisTemplate(RedisTemplate<String, ?> redisTemplate) {
this.redisTemplate = redisTemplate;
}
private final String MUTEX_KEY="mutex";
/**
* 设置失效时间
*
* @param k redisKey
* @param seconds 秒
*/
public <K> void expire(K k, long seconds) {
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
connection.expire(getKeySerializer().serialize(k), seconds);
return null;
}
});
}
/**
* 设置key-value
*
* @author zhangxiaosong
*/
public <K, V> void set(K k, V v) {
final RedisSerializer keySeri = redisTemplate.getKeySerializer();
final RedisSerializer valueSeri = redisTemplate.getValueSerializer();
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
connection.set(keySeri.serialize(k), valueSeri.serialize(v));
return null;
}
});
}
/**
* 如不不存在则设置
*
* @author zhangxiaosong
*/
public <K, V> Boolean setnx(K k, V v) {
final RedisSerializer keySeri = redisTemplate.getKeySerializer();
final RedisSerializer valueSeri = redisTemplate.getValueSerializer();
return redisTemplate.execute(new RedisCallback<Boolean>() {
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
return connection.setNX(keySeri.serialize(k), valueSeri.serialize(v));
}
});
}
/**
* 判定key是否存在
*/
public <K> Boolean exists(K k) {
final RedisSerializer keySeri = redisTemplate.getKeySerializer();
return redisTemplate.execute(new RedisCallback<Boolean>() {
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
return connection.exists(keySeri.serialize(k));
}
});
}
/**
* 设置key-value,包括失效时间
*
* @param seconds 如果小于0 则永久
* @author zhangxiaosong
*/
public <K, V> void set(K k, V v, long seconds) {
final RedisSerializer keySeri = redisTemplate.getKeySerializer();
final RedisSerializer valueSeri = redisTemplate.getValueSerializer();
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
if (seconds > 0) {
connection
.set(keySeri.serialize(k), valueSeri.serialize(v),
Expiration.seconds(seconds),
SetOption.UPSERT);
} else {
connection
.set(keySeri.serialize(k), valueSeri.serialize(v));
}
return null;
}
});
}
/**
* 获取剩余存活时间
*
* @param k key
* @param timeUnit 时间单位
*/
public <K> Long ttl(K k, TimeUnit timeUnit) {
final RedisSerializer keySeri = redisTemplate.getKeySerializer();
return redisTemplate.execute(new RedisCallback<Long>() {
@Override
public Long doInRedis(RedisConnection connection) throws DataAccessException {
return connection.ttl(keySeri.serialize(k), timeUnit);
}
});
}
/**
* 获取剩余存活时间
*
* @param k key
*/
public <K> Long ttl(K k) {
final RedisSerializer keySeri = redisTemplate.getKeySerializer();
return redisTemplate.execute(new RedisCallback<Long>() {
@Override
public Long doInRedis(RedisConnection connection) throws DataAccessException {
return connection.ttl(keySeri.serialize(k));
}
});
}
/**
* 自增
*
* @param k key
* @param step 每次增加多少
*/
public <K> Long incr(K k, long step) {
final RedisSerializer keySeri = redisTemplate.getKeySerializer();
return redisTemplate.execute(new RedisCallback<Long>() {
@Override
public Long doInRedis(RedisConnection connection) throws DataAccessException {
return connection.incrBy(keySeri.serialize(k), step);
}
});
}
/**
* 批量设置,非pipeline
*
* @param map 多个key-value
* @param seconds 如果空则永久
*/
public <K, V> void sets(Map<K, V> map, Long seconds) {
if (map == null) {
return;
}
final RedisSerializer keySeri = redisTemplate.getKeySerializer();
final RedisSerializer valueSeri = redisTemplate.getValueSerializer();
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
Set<Map.Entry<K, V>> entries = map.entrySet();
for (Map.Entry<K, V> entry : entries) {
K k = entry.getKey();
V v = entry.getValue();
if (seconds == null) {
connection
.set(keySeri.serialize(k), valueSeri.serialize(v));
} else {
connection
.set(keySeri.serialize(k), valueSeri.serialize(v),
Expiration.seconds(seconds),
SetOption.UPSERT);
}
}
return null;
}
});
}
/**
* 删除指定的可以
*/
public <K> void del(K k) {
final RedisSerializer keySeri = redisTemplate.getKeySerializer();
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
connection.del(keySeri.serialize(k));
return null;
}
});
}
/**
* pipeline形式设置
*
* @param map 多个key-vlaue值
* @param seconds 如果空则永久
*/
public <K, V> void pipelineSets(final Map<K, V> map, final Long seconds) {
if (map == null || map.isEmpty()) {
return;
}
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
//JedisCluster 暂时不支持pipeline
if (!(connection instanceof JedisClusterConnection)) {
connection.openPipeline();
}
Set<Map.Entry<K, V>> entries = map.entrySet();
for (Map.Entry<K, V> entry : entries) {
if (seconds != null && seconds > 0) {
connection.set(getKeySerializer().serialize(entry.getKey()),
getValueSerializer().serialize(entry.getValue()),
Expiration.seconds(seconds),
SetOption.UPSERT);
} else {
connection.set(getKeySerializer().serialize(entry.getKey()),
getValueSerializer().serialize(entry.getValue()));
}
}
if (!(connection instanceof JedisClusterConnection)) {
connection.closePipeline();
}
return null;
}
}, true);
}
/**
* 批量写入key-value,JSON序列化
*
* @author zhangxiaosong
* @date 2017年12月17日 下午5:09:24
*/
public <K, V> void multiSet(final Map<K, V> map, String prefix, final Long seconds) {
if (map == null || map.isEmpty()) {
return;
}
final Map<String, V> mapStr = new HashMap<>();
for (Map.Entry<K, V> entry : map.entrySet()) {
if (entry.getKey() == null || entry.getValue() == null) {
continue;
}
if (StringUtil.isNotBlank(prefix)) {
mapStr.put(prefix + entry.getKey().toString(), entry.getValue());
} else {
mapStr.put(entry.getKey().toString(), entry.getValue());
}
}
if (!mapStr.isEmpty()) {
if (mapStr.size() < 10) {
sets(mapStr, seconds);
} else {
pipelineSets(mapStr, seconds);
}
}
}
/**
* key value get方法
*/
public <K, V> V get(K k, Class<V> v) {
if (k == null) {
return null;
}
V ret = redisTemplate.execute(new RedisCallback<V>() {
@Override
public V doInRedis(RedisConnection connection) throws DataAccessException {
byte[] bytes = connection.get(getKeySerializer().serialize(k));
return (V) getValueSerializer().deserialize(bytes);
}
});
return ret;
}
/**
* 循环取值,非pipeline形式。如果多 @see pipelineGet()
*
* @param keys 少量keys
*/
public <K, V> List<V> gets(final List<K> keys, Class<V> v) {
List<V> list = new ArrayList<>();
if (keys == null || keys.size() == 0) {
return list;
}
for (K k : keys) {
list.add(get(k, v));
}
return list;
}
/**
* pipeline形式取值
*
* @author zhangxiaosong
*/
public <K, V> List<V> pipelineGets(final List<K> keys, Class<V> v) {
List<V> list = new ArrayList<>();
if (keys == null || keys.size() == 0) {
return list;
}
return redisTemplate.execute(new RedisCallback<List<V>>() {
@Override
public List<V> doInRedis(RedisConnection connection) throws DataAccessException {
connection.openPipeline();
for (K key : keys) {
connection.get(getKeySerializer().serialize(key));
}
List<Object> objectList = connection.closePipeline();
List<V> vList = new ArrayList<V>();
for (Object obj : objectList) {
byte[] objB = (byte[]) obj;
Object o = getValueSerializer().deserialize(objB);
vList.add((V) o);
}
return vList;
}
});
}
/**
* 批量查询redis ,list转换成map返回
*
* @param keys 业务值 ,redisKey=prefix+keys
* @param prefix key前缀
* @author zhangxiaosong
* @date 2017年12月17日 下午4:49:21
*/
public <K, V> Map<K, V> multiGet2Map(List<K> keys, String prefix, Class<V> cls) {
Map<K, V> maps = new HashMap();
if (CollectionUtil.isEmpty(keys)) {
return maps;
}
List<String> newKeys = new ArrayList<String>(keys.size());
for (K key : keys) {
if (key == null) {
newKeys.add(null);
}
if (StringUtil.isBlank(prefix)) {
newKeys.add(key.toString());
} else {
newKeys.add(prefix + key.toString());
}
}
if (newKeys.size() == 0) {
return maps;
}
List<V> list = null;
if (newKeys.size() < 10) {
list = gets(newKeys, cls);
} else {
list = pipelineGets(newKeys, cls);
}
for (int i = 0; i < list.size(); i++) {
V rv = list.get(i);
K rk = keys.get(i);
if (rk != null && rv != null) {
// JSON序列化
maps.put(rk, rv);
}
}
return maps;
}
/**
* 设置key-fileld-value
*
* @author zhangxiaosong
*/
public <K, F, V> void hSet(K k, F f, V v) {
final RedisSerializer keySeri = redisTemplate.getKeySerializer();
final RedisSerializer hashKeySeri = redisTemplate.getHashKeySerializer();
final RedisSerializer hashValueSeri = redisTemplate.getHashValueSerializer();
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
connection.hSet(keySeri.serialize(k), hashKeySeri.serialize(f),
hashValueSeri.serialize(v));
return null;
}
});
}
/**
* 设置哈希表key-fileld-value,当且仅当域 field 不存在
*
* @param k 键
* @param f 哈希表域
* @param v 哈希表值
*/
public <K, F, V> void hSetNX(K k, F f, V v) {
final RedisSerializer keySeri = redisTemplate.getKeySerializer();
final RedisSerializer hashKeySeri = redisTemplate.getHashKeySerializer();
final RedisSerializer hashValueSeri = redisTemplate.getHashValueSerializer();
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
connection.hSetNX(keySeri.serialize(k), hashKeySeri.serialize(f),
hashValueSeri.serialize(v));
return null;
}
});
}
/**
* 为哈希表 key 中的域 field 的值加上增量 increment
*
* @param k key
* @param f field
* @param increment 增量
*/
public <K, F> Long hIncrBy(K k, F f, Long increment) {
final RedisSerializer keySeri = redisTemplate.getKeySerializer();
final RedisSerializer hashKeySeri = redisTemplate.getHashKeySerializer();
final RedisSerializer hashValueSeri = redisTemplate.getHashValueSerializer();
return redisTemplate.execute(new RedisCallback<Long>() {
@Override
public Long doInRedis(RedisConnection connection) throws DataAccessException {
Long val = connection.hIncrBy(keySeri.serialize(k), hashKeySeri.serialize(f), increment);
return val;
}
});
}
/**
* 批量hmset
*
* @param k key
* @param map field-value
*/
public <K, F, V> void hMSet(K k, Map<F, V> map) {
if (map == null || map.size() == 0) {
return;
}
final RedisSerializer keySeri = redisTemplate.getKeySerializer();
final RedisSerializer hashKeySeri = redisTemplate.getHashKeySerializer();
final RedisSerializer hashValueSeri = redisTemplate.getHashValueSerializer();
Map<byte[], byte[]> byteMap = new HashMap<>();
for (Map.Entry<F, V> ety : map.entrySet()) {
byteMap.put(hashKeySeri.serialize(ety.getKey()),
hashValueSeri.serialize(ety.getValue()));
}
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
connection.hMSet(keySeri.serialize(k), byteMap);
return null;
}
});
}
/**
* key field value get方法
*/
public <K, F, V> V hGet(K k, F f, Class<V> v) {
if (k == null) {
return null;
}
V ret = redisTemplate.execute(new RedisCallback<V>() {
@Override
public V doInRedis(RedisConnection connection) throws DataAccessException {
byte[] bytes = connection
.hGet(getKeySerializer().serialize(k), getHashKeySerializer().serialize(f));
return (V) getHashValueSerializer().deserialize(bytes);
}
});
return ret;
}
/**
* hash接口批量获取
*
* @param k key
* @param fields 字段数据
*/
public <K, F, V> Map<F, V> hMGet(K k, F[] fields, Class<V> v) {
final Map<F, V> ret = new HashMap();
if (fields == null || fields.length == 0) {
return ret;
}
byte[][] byteFields = new byte[fields.length][];
for (int i = 0; i < fields.length; i++) {
byteFields[i] = getHashKeySerializer().serialize(fields[i]);
}
return redisTemplate.execute(new RedisCallback<Map<F, V>>() {
@Override
public Map<F, V> doInRedis(RedisConnection connection) throws DataAccessException {
List<byte[]> bytes = connection.hMGet(getKeySerializer().serialize(k), byteFields);
for (int i = 0; i < fields.length; i++) {
if (bytes.get(i) != null) {
ret.put(fields[i],
(V) getHashValueSerializer().deserialize(bytes.get(i)));
}
}
return ret;
}
});
}
public <K, F, V> Map<F, V> hGetAll(K k, Class<F> f, Class<V> v) {
final Map<F, V> ret = new HashMap();
return redisTemplate.execute(new RedisCallback<Map<F, V>>() {
@Override
public Map<F, V> doInRedis(RedisConnection connection) throws DataAccessException {
Map<byte[], byte[]> bytes = connection.hGetAll(getKeySerializer().serialize(k));
for (Map.Entry<byte[], byte[]> ety : bytes.entrySet()) {
ret.put((F) getHashKeySerializer().deserialize(ety.getKey()),
(V) getHashValueSerializer().deserialize(ety.getValue()));
}
return ret;
}
});
}
private RedisSerializer getKeySerializer() {
return redisTemplate.getKeySerializer();
}
private RedisSerializer getValueSerializer() {
return redisTemplate.getValueSerializer();
}
private RedisSerializer getHashKeySerializer() {
return redisTemplate.getHashKeySerializer();
}
private RedisSerializer getHashValueSerializer() {
return redisTemplate.getHashValueSerializer();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>matrix</artifactId>
<groupId>com.secoo.mall</groupId>
<version>1.3.2.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>matrix-datahelper</artifactId>
<packaging>pom</packaging>
<modules>
<module>matrix-datahelper-redis-core</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-datahelper-redis-core</artifactId>
<version>1.3.2.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
\ No newline at end of file
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
<module>matrix-job</module> <module>matrix-job</module>
<module>matrix-bigdata</module> <module>matrix-bigdata</module>
<module>matrix-bus</module> <module>matrix-bus</module>
<module>matrix-datahelper</module>
</modules> </modules>
...@@ -170,6 +171,12 @@ ...@@ -170,6 +171,12 @@
<artifactId>matrix-bigdata-hbase-starter</artifactId> <artifactId>matrix-bigdata-hbase-starter</artifactId>
<version>1.3.2.RELEASE</version> <version>1.3.2.RELEASE</version>
</dependency> </dependency>
<!--redis-->
<!-- <dependency>
<groupId>com.secoo.mall</groupId>
<artifactId>matrix-datahelper-redis-starter</artifactId>
<version>1.3.2.RELEASE</version>
</dependency>-->
<!--普通jar--> <!--普通jar-->
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment