目录
配置yml
引入redis对应的jar
启动本地redis
RedisDesktopManager本地连接查看下对应的redis
RedisTemplate新增一条数据
乱码
序列化RedisTemplate
再次执行写入redis,数据正常
RedisTemplate进行封装。
service
impl
工具类CommonFunctions,常量RedisConstans,JSONUtils
验证
或者添加到对应的properties都是可以的
redis: host: localhot port: 6379 password: 123456
org.springframework.boot
spring-boot-starter-data-redis
com.alibaba
fastjson
1.2.83
com.google.code.gson
gson
2.8.5
可视化客户端解压即用。博文附带可视化客户端、
连接成功
现在我们看到里面有两个key值,k1和password
我现在新增一个key为redis1
但是新增完之后明显是乱码,这时候我们需要对RedisTemplate进行序列化操作
方便我们后续对RedisTemplate的操作,单独操作RedisTemplate太麻烦,太繁琐。
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* redisConfig配置
*/
@Configuration
public class RedisConfig {
/**
* 初始化RedisTemplate 模版序列化操作
*
* @param factory
* @return
*/
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
// 我们为了自己开发方便,一般直接使用
RedisTemplate template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// Json序列化配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// String 的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
import java.util.List;
import java.util.Map;
/**
* Redis操作
*
* @author ex_yangqiusheng
* @Date 2020-5-19 19:19:30
*/
public interface RedisService {
/**
* 设置给定 key 的值并设置时间
* 如果 key 已经存储其他值, SET 就覆写旧值
*
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 ; time等于-1 将设置无限期
* @return true成功 false 失败
*/
boolean set(String key, Object value, long time);
/**
* 设置给定 key 的值并设置时间
* 如果 key 已经存储其他值, SET 就覆写旧值
* 默认无限期
*
* @param key 键
* @param value 值
* @return true成功 false 失败
*/
boolean set(String key, Object value);
/**
* 获取指定 key 的值。
* 如果 key 不存在,返回 null
*
* @param key
* @param clazz 需要转换的对象,不需要转换时,为null
* @return 返回 key 的值,如果 key 不存在时,返回 null
*/
T get(String key, Class clazz);
/**
* 删除缓存
* 删除已存在的键。不存在的 key 会被忽略
*
* @param key 可以传一个值 或多个
* @return 被删除 key 的数量
*/
boolean delete(String... key);
/**
* 指定缓存失效时间
*
* @param key 键
* @param time 时间(秒)
* @return
*/
boolean expire(String key, long time);
/**
* 根据key 获取过期时间
*
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
long getExpireByKey(String key);
/**
* 哈希表中的字段赋值
* 如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作。
* 如果字段已经存在于哈希表中,旧值将被覆盖。
*
* @param key 主键KEY
* @param item 细项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
boolean setHash(String key, String item, Object value, long time);
/**
* 哈希表中的字段赋值
* 如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作。
* 如果字段已经存在于哈希表中,旧值将被覆盖。
*
* @param key 主键KEY
* @param item 细项
* @param value 值
* @return true 成功 false失败
*/
boolean setHash(String key, String item, Object value);
/**
* 返回哈希表中指定字段的值
*
* @param key 键
* @param item 项
* @param clazz 需要转换的对象,不需要转换时,为null
* @return 返回给定字段的值。如果给定的字段或 key 不存在时,返回 null 。
*/
T getHash(String key, String item, Class clazz);
/**
* 同时将多个 field-value (字段-值)对设置到哈希表中。
* 此命令会覆盖哈希表中已存在的字段。
* 如果哈希表不存在,会创建一个空哈希表,并执行 HMSET 操作。
*
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
boolean setMap(String key, Map map, long time);
/**
* 同时将多个 field-value (字段-值)对设置到哈希表中。
* 此命令会覆盖哈希表中已存在的字段。
* 如果哈希表不存在,会创建一个空哈希表,并执行 HMSET 操作。
*
* @param key 键
* @param map 对应多个键值
* @return true成功 false失败
*/
boolean setMap(String key, Map map);
/**
* 获取hashKey对应的所有键值
*
* @param key 键
* @return 以列表形式返回哈希表的字段及字段值。 若 key 不存在,返回空列表。
*/
Map
注:封装对应的方法,再上面最好加上对应的自己封装的异常会更好一些
例如
boolean set(String key, Object value, long time) throws BussinessException;
import CommonFunctions;
import RedisConstans;
import RedisService;
import cn.axa.ruleengine.modules.redis.utils.JSONUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
;
/**
* Redis实现
*
* @author ex_yangqiusheng
* @Date 2020-5-20 21:23:37
*/
@Slf4j
@Service
public class RedisServiceImpl implements RedisService {
@Autowired
private RedisTemplate redisTemplate;
/**
* 设置给定 key 的值并设置时间
* 如果 key 已经存储其他值, SET 就覆写旧值
*
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 ; time等于-1 将设置无限期
* @return true成功 false 失败
*/
@Override
public boolean set(String key, Object value, long time) {
try {
// Object stringValue = "";
// if (!CommonFunctions.isEmpty(value) && !RedisConstans.isBaseType(value)) {
// stringValue = RedisConstans.getStringValue(value);
// } else {
// stringValue = value;
// }
redisTemplate.opsForValue().set(key, value);
expire(key, time);
return true;
} catch (Exception e) {
log.error(RedisConstans.REDIS_ERROR + key, e);
return false;
}
}
@Override
public boolean set(String key, Object value) {
try {
// Object stringValue = "";
// if (!CommonFunctions.isEmpty(value) && !RedisConstans.isBaseType(value)) {
// stringValue = RedisConstans.getStringValue(value);
// } else {
// stringValue = value;
// }
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
log.error(RedisConstans.REDIS_ERROR + key, e);
return false;
}
}
/**
* 获取指定 key 的值。
* 如果 key 不存在,返回 null
*
* @param key
* @param clazz 需要转换的对象,不需要转换时,为null
* @return 返回 key 的值,如果 key 不存在时,返回 null
*/
@Override
public T get(String key, Class clazz) {
try {
Object o = redisTemplate.opsForValue().get(key);
// Object resultObject = RedisConstans.getObject(clazz, o);
return (T) o;
} catch (Exception e) {
log.error(RedisConstans.REDIS_ERROR + key, e);
return null;
}
}
/**
* 删除缓存
* 删除已存在的键。不存在的 key 会被忽略
*
* @param key 可以传一个值 或多个
* @return 被删除 key 的数量
*/
@Override
public boolean delete(String... key) {
try {
if (!CommonFunctions.isEmpty(key) && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
return true;
} catch (Exception e) {
log.error(RedisConstans.REDIS_ERROR + key, e);
return false;
}
}
/**
* 指定缓存失效时间
*
* @param key 键
* @param time 时间(秒)
* @return
*/
@Override
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
log.error(RedisConstans.REDIS_ERROR + key, e);
return false;
}
}
/**
* 根据key 获取过期时间
*
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
@Override
public long getExpireByKey(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
@Override
public boolean setHash(String key, String item, Object value, long time) {
try {
String stringValue = "";
if (!CommonFunctions.isEmpty(value)) {
stringValue = RedisConstans.getStringValue(value);
}
redisTemplate.opsForHash().put(key, item, stringValue);
expire(key, time);
return true;
} catch (Exception e) {
log.error(RedisConstans.REDIS_ERROR + key + item, e);
return false;
}
}
@Override
public boolean setHash(String key, String item, Object value) {
try {
// String stringValue = "";
// if (!CommonFunctions.isEmpty(value)) {
// stringValue = RedisConstans.getStringValue(value);
// }
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
log.error(RedisConstans.REDIS_ERROR + key + item, e);
return false;
}
}
@Override
public T getHash(String key, String item, Class clazz) {
try {
Object o = redisTemplate.opsForHash().get(key, item);
// Object resultObject = RedisConstans.getObject(clazz, o);
// return (T) resultObject;
return (T) o;
} catch (Exception e) {
log.error(RedisConstans.REDIS_ERROR + key + item, e);
return null;
}
}
@Override
public boolean setMap(String key, Map map, long time) {
try {
Map mapValue = new HashMap();
if (map.size() != 0) {
mapValue = RedisConstans.getMapValue(map);
}
redisTemplate.opsForHash().putAll(key, mapValue);
expire(key, time);
return true;
} catch (Exception e) {
log.error(RedisConstans.REDIS_ERROR + key, e);
return false;
}
}
@Override
public boolean setMap(String key, Map map) {
try {
Map mapValue = new HashMap();
if (map.size() != 0) {
mapValue = RedisConstans.getMapValue(map);
}
redisTemplate.opsForHash().putAll(key, mapValue);
return true;
} catch (Exception e) {
log.error(RedisConstans.REDIS_ERROR + key, e);
return false;
}
}
@Override
public Map
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 验空Utils
*/
@Slf4j
public class CommonFunctions {
/**
* 判空方法
*
* @param object
* @return
*/
public static boolean isEmpty(Object object) {
if (object == null || object.toString().trim().length() == 0) {
return true;
} else {
return false;
}
}
/**
* 判空方法
*
* @param list
* @return
*/
public static boolean isEmpty(List list) {
if (list == null || list.isEmpty()) {
return true;
} else {
return false;
}
}
/**
* 判空方法
*
* @param object
* @return
*/
public static boolean isNotEmpty(Object object) {
if (object == null || object.toString().trim().length() == 0) {
return false;
} else {
return true;
}
}
/**
* 判空方法
*
* @param list
* @return
*/
public static boolean isNotEmpty(List list) {
if (list == null || list.isEmpty()) {
return false;
} else {
return true;
}
}
/**
* 判空方法
*
* @param set
* @return
*/
public static boolean isNotEmpty(Set set) {
if (set == null || set.isEmpty()) {
return false;
} else {
return true;
}
}
/**
* 判空方法
*
* @param set
* @return
*/
public static boolean isEmpty(Set set) {
if (set == null || set.isEmpty()) {
return true;
} else {
return false;
}
}
/**
* 判空方法
*
* @param map
* @return
*/
public static boolean isEmpty(Map map) {
if (map == null || map.isEmpty()) {
return true;
} else {
return false;
}
}
/**
* 判空方法
*
* @param map
* @return
*/
public static boolean isNotEmpty(Map map) {
if (map == null || map.isEmpty()) {
return false;
} else {
return true;
}
}
/**
* 对象克隆方法
*
* @param bean
* @return
*/
public static Object getCloneObject(Object bean) {
Object cloneBean = null;
try {
ByteArrayOutputStream byout = new ByteArrayOutputStream();
ObjectOutputStream obj = new ObjectOutputStream(byout);
obj.writeObject(bean);
ByteArrayInputStream byin = new ByteArrayInputStream(byout.toByteArray());
ObjectInputStream ins = new ObjectInputStream(byin);
cloneBean = (Object) ins.readObject();
} catch (Exception ex) {
ex.printStackTrace();
}
return cloneBean;
}
/**
* 对象转byte
* @param obj
* @return
*/
public static byte[] ObjectToByte(Object obj) {
byte[] bytes = null;
try {
// object to bytearray
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(obj);
bytes = bo.toByteArray();
bo.close();
oo.close();
} catch (Exception e) {
log.error("对象转byte" + e.getMessage());
e.printStackTrace();
}
return bytes;
}
/**
* byte转对象
* @param bytes
* @param obj
* @return
*/
public static Object ByteToObject(Object obj,byte[] bytes) {
try {
// bytearray to object
ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
ObjectInputStream oi = new ObjectInputStream(bi);
obj = (Object) oi.readObject();
bi.close();
oi.close();
} catch (Exception e) {
log.error("byte转对象" + e.getMessage());
e.printStackTrace();
}
return obj;
}
}
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import javax.annotation.PostConstruct;
import java.util.*;
/**
* redis常量
*/
public final class RedisConstans {
/**
* 失效时间---永久有效
*/
public static final long MINUS_ONE = -1L;
/**
* 失效时间---一个月
*/
public static final long MONTH_ONE = 97200L;
/**
* 失效时间---两个小时
*/
public static final long HOUR_TWO = 7200L;
/**
* **********
*/
public static final String DECISION_EXCEL_CACHE = "**********";
/**
* **********
*/
public static final String REDIS_ERROR = "[ ********** ] : ";
/**
* 常量1
*/
public static final String REDIS_ONE = "1";
/**
* 常量2
*/
public static final String REDIS_TWO = "2";
/**
* 常量0
*/
public static final String REDIS_ZERO = "0";
/**
* **********
*/
public static final String REDIS_CACHE_NAME = "**********:";
/**
* **********
*/
public static final String REDIS_CACHE_CALIB_NAME = "**********:**********";
/**
* **********
*/
public static final String REDIS_CACHE_CALIB_COMMON_NAME = "**********:**********";
/**
* **********
*/
public static final String REDIS_CACHE_DEPARTMENT_NAME = "**********:**********";
/**
* **********
*/
public static final String REDIS_CACHE_DEPARTMENT_UPPER_NAME = "**********:**********:**********";
/**
* **********
*/
public static final String REDIS_CACHE_COMMON_DEPARTMENT_NAME = "**********:**********:**********";
/**
* **********
*/
public static final String REDIS_CACHE_NEWRULEENGINE = "**********_";
/**
* **********
*/
public static final String PRE_CACHE_NEWRULEENGINE = "PRE";
/**
* redis拼接KEY ver+ID
*
* @param ver
* @param key
* @return
*/
@PostConstruct
public static String cacheName(String ver, Long key) {
return ver + "_" + key;
}
/**
* redis数据KEY
*
* @param key
* @return
*/
public static String cacheName(Long key, Boolean isPerEffect) {
if (isPerEffect){
return PRE_CACHE_NEWRULEENGINE + REDIS_CACHE_NEWRULEENGINE + key;
}
return REDIS_CACHE_NEWRULEENGINE + key;
}
/**
* 对象转json字符串
*
* @param object 存入对象
* @return
*/
public static String getStringValue(Object object) {
String stringValue = JSON.toJSONString(object);
return stringValue;
}
/**
* json字符串转对象
*
* @param clazz 接收对象
* @param value 缓存对象
* @param clazz 需要转换的对象,不需要转换时,为null
* @return
*/
public static T getObject(Class clazz, Object value) {
if (clazz != null && value != null) {
JSONObject jsonObject = JSON.parseObject(value.toString());
return JSON.toJavaObject(jsonObject, clazz);
}
return (T) value;
}
/**
* 判断object是否为基本类型
*
* @param object
* @return
*/
public static boolean isBaseType(Object object) {
Class className = object.getClass();
if (className.equals(Integer.class) ||
className.equals(Byte.class) ||
className.equals(Long.class) ||
className.equals(Double.class) ||
className.equals(Float.class) ||
className.equals(Character.class) ||
className.equals(Short.class) ||
className.equals(Boolean.class)) {
return true;
}
return false;
}
/**
* 将Map中的对象转为json字符串
*
* @param map 存入对象
* @return
*/
public static Map getMapValue(Map map) {
Map valueMap = new HashMap();
Iterator it = map.keySet().iterator();
while (it.hasNext()) {
String mapKey = it.next().toString();
String mapValue = JSON.toJSONString(map.get(mapKey));
valueMap.put(mapKey, mapValue);
}
return valueMap;
}
/**
* 将List中的对象转为json字符串
*
* @param list 存入对象
* @return
*/
public static List getListValue(List list) {
List listStr = new ArrayList<>(list.size());
for (int i = 0; i < list.size(); i++) {
String str = JSON.toJSONString(list.get(i));
listStr.add(i, str);
}
return listStr;
}
}
import CommonFunctions;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
/**
* JsonUtils
*/
@Slf4j
public class JSONUtils {
/**
* json转对应对象
*
* @param valueList 转值对象
* @param clazz 类型
* @param 返回类型
* @return
*/
public static List JsonToClass(List valueList, Class clazz) {
try {
if (CommonFunctions.isNotEmpty(valueList)) {
List collect = valueList.stream().map(v -> {
T t = jsonToBean(v.toString(), clazz);
return t;
}).collect(Collectors.toList());
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return null;
}
/**
* json字符串转bean对象
* @param json
* @param clazz
* @param
* @return
*/
public static T jsonToBean(String json, Class clazz) {
if (CommonFunctions.isNotEmpty(json) && CommonFunctions.isNotEmpty(clazz)) {
try {
T newInstance = clazz.newInstance();
return (T) JSONObject.parseObject(json, newInstance.getClass());
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
}
return null;
}
public static String toJson(Object obj) {
Gson gson = new Gson();
return gson.toJson(obj);
}
public static String toJson(Object obj, Type type) {
Gson gson = new Gson();
return gson.toJson(obj, type);
}
public static String toJson(Collection collection) {
Gson gson = new Gson();
return gson.toJson(collection);
}
public static String toJson(Collection collection, Type type) {
Gson gson = new Gson();
return gson.toJson(collection, type);
}
public static T toObject(String json, Type type) {
Gson gson = new Gson();
return (T) gson.fromJson(json, type);
}
public static List toObject(String jsonString, Class type) {
Gson gson = new Gson();
T[] list = gson.fromJson(jsonString, type);
return Arrays.asList(list);
}
public static T toObject(String json, TypeToken token) {
Gson gson = new Gson();
return (T) gson.fromJson(json, token.getType());
}
}
测试成功!上面代码即办即用。感谢大家三连