最近项目中有遇到需加分布式锁问题,记录一下整理的Redis工具类,
含有redis存储Object的几种方式:1、对象序列化存储。2、对象转json串存储。3、hash类型chun存储。
以下是代码:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.cslp.ilea.distribute.entity.Person;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class RedisUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(RedisUtil.class);
private static final String SUCCESS_OK = "OK";
private static final Long SUCCESS_STATUS_LONG = 1L;
// SET IF NOT EXIST,即当key不存在时,我们进行set操作;若key已经存在,则不做任何操作
private static final String SET_IF_NOT_EXIST = "NX";
// 给key加一个过期的设置,具体时间由第五个参数决定
private static final String SET_WITH_EXPIRE_TIME = "PX";
// jedis server url
public static final String JEDIS_HOST_URL = PropertyUtil.getPropertyByName("JEDIS_HOST_URL");
// jedis server port
public static final int JEDIS_HOST_PORT = Integer.parseInt(PropertyUtil.getPropertyByName("JEDIS_HOST_PORT"));
// jedis server paw
public static final String JEDIS_HOST_PASSWD = PropertyUtil.getPropertyByName("JEDIS_HOST_PASSWD");
// jedis max active connection
public static final int JEDIS_MAX_ACTIVE = Integer.parseInt(PropertyUtil.getPropertyByName("JEDIS_MAX_ACTIVE"));
// jedis max idle comnnection
public static final int JEDIS_MAX_IDLE = Integer.parseInt(PropertyUtil.getPropertyByName("JEDIS_MAX_IDLE"));
// jedis pool
public static JedisPool pool = null;
public static JedisPool getJedisPool() {
if (pool == null) {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(JEDIS_MAX_IDLE);
config.setTestOnBorrow(true);
pool = new JedisPool(config, JEDIS_HOST_URL, JEDIS_HOST_PORT, 0, JEDIS_HOST_PASSWD);
}
return pool;
}
/**
* 字符串set
*
* @param key
* @param value
* @return
*/
public static boolean set(String key, String value) {
boolean ret = false;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return ret;
}
String status = jedis.set(key, value);
if (SUCCESS_OK.equalsIgnoreCase(status)) {
ret = true;
}
} catch (Exception e) {
LOGGER.error("redis set 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
/**
* 字符串set
*
* @param key
* @param value
* @param seconds
* 单位秒,大于0
* @return
*/
public static boolean set(String key, String value, int seconds) {
boolean ret = false;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return ret;
}
String status = jedis.setex(key, seconds, value);
if (SUCCESS_OK.equalsIgnoreCase(status)) {
ret = true;
}
} catch (Exception e) {
LOGGER.error("redis set 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
/**
* 是否存在key
*
* @param key
* @return
*/
public static boolean isExists(String key) {
boolean ret = false;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return ret;
}
return jedis.exists(key);
} catch (Exception e) {
LOGGER.error("redis isExists 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
/**
* 字符串 删除
*
* @param key
* @return
*/
public static boolean del(String key) {
boolean ret = false;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return ret;
}
Long status = jedis.del(key);
if (SUCCESS_STATUS_LONG == status) {
ret = true;
}
} catch (Exception e) {
LOGGER.error("redis del 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
/**
* 字符串获取
*
* @param key
* @return
*/
public static String get(String key) {
String ret = null;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return ret;
}
ret = jedis.get(key);
} catch (Exception e) {
LOGGER.error("redis get 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
/**
* 获取分布式锁
*
* @param lockKey
* key为锁
* @param requestId
* 加锁请求
* @param expireTime
* key的过期时间
* @return
*/
public static boolean getDistributedLock(String lockKey, String requestId, int expireTime) {
boolean ret = false;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return ret;
}
String status = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
if (SUCCESS_OK.equalsIgnoreCase(status)) {
ret = true;
}
} catch (Exception e) {
LOGGER.error("redis 获取分布式锁 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
/**
* 释放分布式锁
*
* @param lockKey
* @param requestId
*/
public static boolean releaseDistributedLock(String lockKey, String requestId) {
boolean ret = false;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return ret;
}
/*
* 其他请求误解锁问题 if(requestId.equals(jedis.get(lockKey))) { jedis.del(lockKey); }
*/
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object status = jedis.eval(script, Collections.singletonList(lockKey),
Collections.singletonList(requestId));
if (SUCCESS_STATUS_LONG.equals(status)) {
ret = true;
}
} catch (Exception e) {
LOGGER.error("redis 释放分布式锁 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
/**
* 序列化存入对象
*
* @param key
* @param obj
* @return
*/
public static boolean set(byte[] key, Object obj) {
boolean ret = false;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return ret;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
String status = jedis.set(key, baos.toByteArray());
if (SUCCESS_OK.equalsIgnoreCase(status)) {
ret = true;
}
} catch (Exception e) {
LOGGER.error("redis set 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
/**
* 取序列化对象
*
* @param key
* @return
*/
public static Object getObj(byte[] key) {
Object ret = null;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return ret;
}
byte[] rets = jedis.get(key);
ByteArrayInputStream bais = new ByteArrayInputStream(rets);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
LOGGER.error("redis get 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
/**
* hash数据类型存储对象
*
* @param key
* @param obj
* @return
*/
public static boolean setHm(String key, Object obj) {
boolean ret = false;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return ret;
}
Map<String, String> hash = objToMap(obj);
String status = jedis.hmset(key, hash);
if (SUCCESS_OK.equalsIgnoreCase(status)) {
ret = true;
}
} catch (Exception e) {
LOGGER.error("redis setHm 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
/**
* 修改对象属性
*
* @param key
* @param field
* @param value
* @return
*/
public static boolean setHm(String key, String field, String value) {
boolean ret = false;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return ret;
}
Long status = jedis.hset(key, field, value);
if (0L == status) {
ret = true;
}
} catch (Exception e) {
LOGGER.error("redis setHm 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
/**
* 根据fields 查询key对象属性列表
*
* @param key
* @param fields
* @return
*/
public static List<String> getHm(String key, String... fields) {
List<String> ret = null;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return null;
}
ret = jedis.hmget(key, fields);
} catch (Exception e) {
LOGGER.error("redis getHm 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
/**
* 根据field 查询key对象属性
*
* @param key
* @param fields
* @return
*/
public static String getHm(String key, String field) {
String ret = null;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return null;
}
ret = jedis.hget(key, field);
} catch (Exception e) {
LOGGER.error("redis getHm 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
/**
* 根据key查询对象
*
* @param key
* @param fields
* @return
*/
public static Object getHm(String key, Class clazz) {
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return null;
}
Map<String, String> map = jedis.hgetAll(key);
return mapToObj(map, clazz);
} catch (Exception e) {
LOGGER.error("redis getHm 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return null;
}
/**
* json格式存对象
* @param key
* @param obj
* @return
*/
public static boolean setJson(String key,Object obj) {
boolean ret = false;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return ret;
}
ObjectMapper mapper = new ObjectMapper();
String status = jedis.set(key, mapper.writeValueAsString(obj));
if (SUCCESS_OK.equalsIgnoreCase(status)) {
ret = true;
}
} catch (Exception e) {
LOGGER.error("redis setJson 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
/**
* json格式取对象
* @param key
* @param clazz
* @return
*/
public static Object getJson(String key,Class clazz) {
Object ret = null;
Jedis jedis = null;
try {
jedis = getJedisPool().getResource();
if (jedis == null) {
return ret;
}
String str = jedis.get(key);
ObjectMapper mapper = new ObjectMapper();
ret = mapper.readValue(str, clazz);
} catch (Exception e) {
LOGGER.error("redis getJson 出错", e);
pool.returnBrokenResource(jedis);
} finally {
if (null != jedis) {
pool.returnResource(jedis);
}
}
return ret;
}
private static HashMap<String, String> objToMap(Object obj) {
if(null == obj) {
return null;
}
HashMap<String, String> map = new HashMap<String, String>();
Field[] fields = obj.getClass().getDeclaredFields();
try {
for (int i = 0; i < fields.length; i++) {
String varName = fields[i].getName();
boolean accessFlag = fields[i].isAccessible();
fields[i].setAccessible(true);
Object o = fields[i].get(obj);
if (o != null) {
map.put(varName, o.toString());
}
fields[i].setAccessible(accessFlag);
}
} catch (Exception e) {
}
return map;
}
private static Object mapToObj(Map<String, String> map, Class clazz) {
if(null == map) {
return null;
}
try {
Object obj = clazz.newInstance();
Field[] fields = obj.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
String varName = fields[i].getName();
String type = fields[i].getGenericType().getTypeName();
Object value = null;
switch(type) {
case "java.lang.Integer" :
value = Integer.valueOf(map.get(varName));
break;
case "java.lang.Long" :
value = Long.valueOf(map.get(varName));
break;
default:
value = map.get(varName);
}
fields[i].setAccessible(true);
fields[i].set(obj, value);
}
return obj;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
读取配置文件的工具类PropertyUtil
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertyUtil {
private static final String propertyPath = "config.properties";
public static String getPropertyByName(String name) {
return getPropertyByName(propertyPath, name);
}
//path: WEB-INF/classes
// 读取配置文件信息
private static String getPropertyByName(String path, String name)
{
String result = "";
InputStream in = PropertyUtil.class.getClassLoader().getResourceAsStream(path);
Properties prop = new Properties();
try
{
prop.load(in);
result = prop.getProperty(name).trim();
}
catch (IOException e)
{
e.printStackTrace();
}
return result;
}
}
分布式锁参照博客Redis分布式锁的正确实现方式 ,写的很详细。