转载自hbxflihua
1、spring相关配置如下:
- <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
- <property name="maxIdle" value="${redis.pool.maxIdle}" /> <!-- 最大能够保持idel状态的对象数 -->
- <property name="maxTotal" value="${redis.pool.maxTotal}" /> <!-- 最大分配的对象数 -->
- <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" /> <!-- 当调用borrow Object方法时,是否进行有效性检查 -->
- </bean>
- <!-- sprin_data_redis 单机配置 -->
- <bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
- <property name="hostName" value="${redis.host}" />
- <property name="port" value="${redis.port}" />
- <property name="timeout" value="${redis.timeout}" />
- <property name="password" value="${redis.password}" />
- <property name="poolConfig" ref="jedisPoolConfig" />
- </bean>
- <!-- key序列化 -->
- <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
- <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"
- p:connectionFactory-ref="jedisConnFactory" />
- <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
- p:connectionFactory-ref="jedisConnFactory"
- p:keySerializer-ref="stringRedisSerializer"
- p:hashKeySerializer-ref="stringRedisSerializer" />
- <!-- spring自己的缓存管理器 -->
- <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
- <property name="caches">
- <set>
- <bean class="com.rd.ifaes.common.jedis.RdRedisCache" p:redis-template-ref="redisTemplate" p:name="sysCache"/>
- </set>
- </property>
- </bean>
- <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
- <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true" />
2、缓存工具类CacheUtils
- package com.lh.core.core.util;
- import java.util.Map;
- import java.util.Set;
- import java.util.concurrent.TimeUnit;
- import org.springframework.data.redis.core.BoundHashOperations;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.data.redis.core.StringRedisTemplate;
- import org.springframework.util.CollectionUtils;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONObject;
- import com.rd.ifaes.common.dict.ExpireTime;
- import com.lh.common.util.JsonMapper;
- import com.rd.ifaes.common.util.SpringContextHolder;
- import com.rd.ifaes.common.util.StringUtils;
- /**
- * 通用缓存工具类
- * @author lh
- * @version 3.0
- * @since 2016-6-22
- *
- */
- public class CacheUtils {
- private static StringRedisTemplate stringRedisTemplate = SpringContextHolder.getBean("stringRedisTemplate");
- private static RedisTemplate<String, Object> redisTemplate = SpringContextHolder.getBean("redisTemplate");
- /**
- * 删除缓存<br>
- * 根据key精确匹配删除
- * @param key
- */
- @SuppressWarnings("unchecked")
- public static void del(String... key){
- if(key!=null && key.length > 0){
- if(key.length == 1){
- redisTemplate.delete(key[0]);
- }else{
- redisTemplate.delete(CollectionUtils.arrayToList(key));
- }
- }
- }
- /**
- * 批量删除<br>
- * (该操作会执行模糊查询,请尽量不要使用,以免影响性能或误删)
- * @param pattern
- */
- public static void batchDel(String... pattern){
- for (String kp : pattern) {
- redisTemplate.delete(redisTemplate.keys(kp + "*"));
- }
- }
- /**
- * 取得缓存(int型)
- * @param key
- * @return
- */
- public static Integer getInt(String key){
- String value = stringRedisTemplate.boundValueOps(key).get();
- if(StringUtils.isNotBlank(value)){
- return Integer.valueOf(value);
- }
- return null;
- }
- /**
- * 取得缓存(字符串类型)
- * @param key
- * @return
- */
- public static String getStr(String key){
- return stringRedisTemplate.boundValueOps(key).get();
- }
- /**
- * 取得缓存(字符串类型)
- * @param key
- * @return
- */
- public static String getStr(String key, boolean retain){
- String value = stringRedisTemplate.boundValueOps(key).get();
- if(!retain){
- redisTemplate.delete(key);
- }
- return value;
- }
- /**
- * 获取缓存<br>
- * 注:基本数据类型(Character除外),请直接使用get(String key, Class<T> clazz)取值
- * @param key
- * @return
- */
- public static Object getObj(String key){
- return redisTemplate.boundValueOps(key).get();
- }
- /**
- * 获取缓存<br>
- * 注:java 8种基本类型的数据请直接使用get(String key, Class<T> clazz)取值
- * @param key
- * @param retain 是否保留
- * @return
- */
- public static Object getObj(String key, boolean retain){
- Object obj = redisTemplate.boundValueOps(key).get();
- if(!retain){
- redisTemplate.delete(key);
- }
- return obj;
- }
- /**
- * 获取缓存<br>
- * 注:该方法暂不支持Character数据类型
- * @param key key
- * @param clazz 类型
- * @return
- */
- @SuppressWarnings("unchecked")
- public static <T> T get(String key, Class<T> clazz) {
- return (T)redisTemplate.boundValueOps(key).get();
- }
- /**
- * 获取缓存json对象<br>
- * @param key key
- * @param clazz 类型
- * @return
- */
- public static <T> T getJson(String key, Class<T> clazz) {
- return JsonMapper.fromJsonString(stringRedisTemplate.boundValueOps(key).get(), clazz);
- }
- /**
- * 将value对象写入缓存
- * @param key
- * @param value
- * @param time 失效时间(秒)
- */
- public static void set(String key,Object value,ExpireTime time){
- if(value.getClass().equals(String.class)){
- stringRedisTemplate.opsForValue().set(key, value.toString());
- }else if(value.getClass().equals(Integer.class)){
- stringRedisTemplate.opsForValue().set(key, value.toString());
- }else if(value.getClass().equals(Double.class)){
- stringRedisTemplate.opsForValue().set(key, value.toString());
- }else if(value.getClass().equals(Float.class)){
- stringRedisTemplate.opsForValue().set(key, value.toString());
- }else if(value.getClass().equals(Short.class)){
- stringRedisTemplate.opsForValue().set(key, value.toString());
- }else if(value.getClass().equals(Long.class)){
- stringRedisTemplate.opsForValue().set(key, value.toString());
- }else if(value.getClass().equals(Boolean.class)){
- stringRedisTemplate.opsForValue().set(key, value.toString());
- }else{
- redisTemplate.opsForValue().set(key, value);
- }
- if(time.getTime() > 0){
- redisTemplate.expire(key, time.getTime(), TimeUnit.SECONDS);
- }
- }
- /**
- * 将value对象以JSON格式写入缓存
- * @param key
- * @param value
- * @param time 失效时间(秒)
- */
- public static void setJson(String key,Object value,ExpireTime time){
- stringRedisTemplate.opsForValue().set(key, JsonMapper.toJsonString(value));
- if(time.getTime() > 0){
- stringRedisTemplate.expire(key, time.getTime(), TimeUnit.SECONDS);
- }
- }
- /**
- * 更新key对象field的值
- * @param key 缓存key
- * @param field 缓存对象field
- * @param value 缓存对象field值
- */
- public static void setJsonField(String key, String field, String value){
- JSONObject obj = JSON.parseObject(stringRedisTemplate.boundValueOps(key).get());
- obj.put(field, value);
- stringRedisTemplate.opsForValue().set(key, obj.toJSONString());
- }
- /**
- * 递减操作
- * @param key
- * @param by
- * @return
- */
- public static double decr(String key, double by){
- return redisTemplate.opsForValue().increment(key, -by);
- }
- /**
- * 递增操作
- * @param key
- * @param by
- * @return
- */
- public static double incr(String key, double by){
- return redisTemplate.opsForValue().increment(key, by);
- }
- /**
- * 获取double类型值
- * @param key
- * @return
- */
- public static double getDouble(String key) {
- String value = stringRedisTemplate.boundValueOps(key).get();
- if(StringUtils.isNotBlank(value)){
- return Double.valueOf(value);
- }
- return 0d;
- }
- /**
- * 设置double类型值
- * @param key
- * @param value
- * @param time 失效时间(秒)
- */
- public static void setDouble(String key, double value, ExpireTime time) {
- stringRedisTemplate.opsForValue().set(key, String.valueOf(value));
- if(time.getTime() > 0){
- stringRedisTemplate.expire(key, time.getTime(), TimeUnit.SECONDS);
- }
- }
- /**
- * 设置double类型值
- * @param key
- * @param value
- * @param time 失效时间(秒)
- */
- public static void setInt(String key, int value, ExpireTime time) {
- stringRedisTemplate.opsForValue().set(key, String.valueOf(value));
- if(time.getTime() > 0){
- stringRedisTemplate.expire(key, time.getTime(), TimeUnit.SECONDS);
- }
- }
- /**
- * 将map写入缓存
- * @param key
- * @param map
- * @param time 失效时间(秒)
- */
- public static <T> void setMap(String key, Map<String, T> map, ExpireTime time){
- redisTemplate.opsForHash().putAll(key, map);
- }
- /**
- * 将map写入缓存
- * @param key
- * @param map
- * @param time 失效时间(秒)
- */
- @SuppressWarnings("unchecked")
- public static <T> void setMap(String key, T obj, ExpireTime time){
- Map<String, String> map = (Map<String, String>)JsonMapper.parseObject(obj, Map.class);
- redisTemplate.opsForHash().putAll(key, map);
- }
- /**
- * 向key对应的map中添加缓存对象
- * @param key
- * @param map
- */
- public static <T> void addMap(String key, Map<String, T> map){
- redisTemplate.opsForHash().putAll(key, map);
- }
- /**
- * 向key对应的map中添加缓存对象
- * @param key cache对象key
- * @param field map对应的key
- * @param value 值
- */
- public static void addMap(String key, String field, String value){
- redisTemplate.opsForHash().put(key, field, value);
- }
- /**
- * 向key对应的map中添加缓存对象
- * @param key cache对象key
- * @param field map对应的key
- * @param obj 对象
- */
- public static <T> void addMap(String key, String field, T obj){
- redisTemplate.opsForHash().put(key, field, obj);
- }
- /**
- * 获取map缓存
- * @param key
- * @param clazz
- * @return
- */
- public static <T> Map<String, T> mget(String key, Class<T> clazz){
- BoundHashOperations<String, String, T> boundHashOperations = redisTemplate.boundHashOps(key);
- return boundHashOperations.entries();
- }
- /**
- * 获取map缓存
- * @param key
- * @param clazz
- * @return
- */
- public static <T> T getMap(String key, Class<T> clazz){
- BoundHashOperations<String, String, String> boundHashOperations = redisTemplate.boundHashOps(key);
- Map<String, String> map = boundHashOperations.entries();
- return JsonMapper.parseObject(map, clazz);
- }
- /**
- * 获取map缓存中的某个对象
- * @param key
- * @param field
- * @param clazz
- * @return
- */
- @SuppressWarnings("unchecked")
- public static <T> T getMapField(String key, String field, Class<T> clazz){
- return (T)redisTemplate.boundHashOps(key).get(field);
- }
- /**
- * 删除map中的某个对象
- * @author lh
- * @date 2016年8月10日
- * @param key map对应的key
- * @param field map中该对象的key
- */
- public void delMapField(String key, String... field){
- BoundHashOperations<String, String, ?> boundHashOperations = redisTemplate.boundHashOps(key);
- boundHashOperations.delete(field);
- }
- /**
- * 指定缓存的失效时间
- *
- * @author FangJun
- * @date 2016年8月14日
- * @param key 缓存KEY
- * @param time 失效时间(秒)
- */
- public static void expire(String key, ExpireTime time) {
- if(time.getTime() > 0){
- redisTemplate.expire(key, time.getTime(), TimeUnit.SECONDS);
- }
- }
- /**
- * 添加set
- * @param key
- * @param value
- */
- public static void sadd(String key, String... value) {
- redisTemplate.boundSetOps(key).add(value);
- }
- /**
- * 删除set集合中的对象
- * @param key
- * @param value
- */
- public static void srem(String key, String... value) {
- redisTemplate.boundSetOps(key).remove(value);
- }
- /**
- * set重命名
- * @param oldkey
- * @param newkey
- */
- public static void srename(String oldkey, String newkey){
- redisTemplate.boundSetOps(oldkey).rename(newkey);
- }
- /**
- * 短信缓存
- * @author fxl
- * @date 2016年9月11日
- * @param key
- * @param value
- * @param time
- */
- public static void setIntForPhone(String key,Object value,int time){
- stringRedisTemplate.opsForValue().set(key, JsonMapper.toJsonString(value));
- if(time > 0){
- stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
- }
- }
- /**
- * 模糊查询keys
- * @param pattern
- * @return
- */
- public static Set<String> keys(String pattern){
- return redisTemplate.keys(pattern);
- }
- }
3、JsonMaper
- package com.lh.common.util;
- import java.io.IOException;
- import java.util.TimeZone;
- import org.apache.commons.lang3.StringEscapeUtils;
- import org.apache.commons.lang3.StringUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import com.alibaba.fastjson.JSON;
- import com.fasterxml.jackson.annotation.JsonInclude.Include;
- import com.fasterxml.jackson.core.JsonGenerator;
- import com.fasterxml.jackson.core.JsonParser.Feature;
- import com.fasterxml.jackson.core.JsonProcessingException;
- import com.fasterxml.jackson.databind.DeserializationFeature;
- import com.fasterxml.jackson.databind.JavaType;
- import com.fasterxml.jackson.databind.JsonSerializer;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.fasterxml.jackson.databind.SerializationFeature;
- import com.fasterxml.jackson.databind.SerializerProvider;
- import com.fasterxml.jackson.databind.module.SimpleModule;
- import com.fasterxml.jackson.databind.util.JSONPObject;
- import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
- /**
- * 简单封装Jackson,实现JSON String<->Java Object的Mapper.
- *
- */
- public class JsonMapper extends ObjectMapper {
- private static final long serialVersionUID = 1L;
- private final static Logger LOGGER = LoggerFactory.getLogger(JsonMapper.class);
- private static JsonMapper mapper;
- public JsonMapper() {
- this(Include.NON_EMPTY);
- }
- public JsonMapper(Include include) {
- // 设置输出时包含属性的风格
- if (include != null) {
- this.setSerializationInclusion(include);
- }
- // 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
- this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
- // 空值处理为空串
- this.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>(){
- @Override
- public void serialize(Object value, JsonGenerator jgen,
- SerializerProvider provider) throws IOException,
- JsonProcessingException {
- jgen.writeString("");
- }
- });
- // 进行HTML解码。
- this.registerModule(new SimpleModule().addSerializer(String.class, new JsonSerializer<String>(){
- @Override
- public void serialize(String value, JsonGenerator jgen,
- SerializerProvider provider) throws IOException,
- JsonProcessingException {
- jgen.writeString(StringEscapeUtils.unescapeHtml4(value));
- }
- }));
- // 设置时区
- this.setTimeZone(TimeZone.getDefault());//getTimeZone("GMT+8:00")
- }
- /**
- * 创建只输出非Null且非Empty(如List.isEmpty)的属性到Json字符串的Mapper,建议在外部接口中使用.
- */
- public static JsonMapper getInstance() {
- if (mapper == null){
- mapper = new JsonMapper().enableSimple();
- }
- return mapper;
- }
- /**
- * 创建只输出初始值被改变的属性到Json字符串的Mapper, 最节约的存储方式,建议在内部接口中使用。
- */
- public static JsonMapper nonDefaultMapper() {
- if (mapper == null){
- mapper = new JsonMapper(Include.NON_DEFAULT);
- }
- return mapper;
- }
- /**
- * Object可以是POJO,也可以是Collection或数组。
- * 如果对象为Null, 返回"null".
- * 如果集合为空集合, 返回"[]".
- */
- public String toJson(Object object) {
- try {
- return this.writeValueAsString(object);
- } catch (IOException e) {
- if(LOGGER.isWarnEnabled()){
- LOGGER.warn("write to json string error:" + object, e);
- }
- return null;
- }
- }
- /**
- * 反序列化POJO或简单Collection如List<String>.
- *
- * 如果JSON字符串为Null或"null"字符串, 返回Null.
- * 如果JSON字符串为"[]", 返回空集合.
- *
- * 如需反序列化复杂Collection如List<MyBean>, 请使用fromJson(String,JavaType)
- * @see #fromJson(String, JavaType)
- */
- public <T> T fromJson(String jsonString, Class<T> clazz) {
- if (StringUtils.isEmpty(jsonString)) {
- return null;
- }
- try {
- return this.readValue(jsonString, clazz);
- } catch (IOException e) {
- if(LOGGER.isWarnEnabled()){
- LOGGER.warn("parse json string error:" + jsonString, e);
- }
- return null;
- }
- }
- /**
- * 反序列化复杂Collection如List<Bean>, 先使用函數createCollectionType构造类型,然后调用本函数.
- * @see #createCollectionType(Class, Class...)
- */
- @SuppressWarnings("unchecked")
- public <T> T fromJson(String jsonString, JavaType javaType) {
- if (StringUtils.isEmpty(jsonString)) {
- return null;
- }
- try {
- return (T) this.readValue(jsonString, javaType);
- } catch (IOException e) {
- if(LOGGER.isWarnEnabled()){
- LOGGER.warn("parse json string error:" + jsonString, e);
- }
- return null;
- }
- }
- /**
- * 構造泛型的Collection Type如:
- * ArrayList<MyBean>, 则调用constructCollectionType(ArrayList.class,MyBean.class)
- * HashMap<String,MyBean>, 则调用(HashMap.class,String.class, MyBean.class)
- */
- public JavaType createCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
- return this.getTypeFactory().constructParametricType(collectionClass, elementClasses);
- }
- /**
- * 當JSON裡只含有Bean的部分屬性時,更新一個已存在Bean,只覆蓋該部分的屬性.
- */
- @SuppressWarnings("unchecked")
- public <T> T update(String jsonString, T object) {
- try {
- return (T) this.readerForUpdating(object).readValue(jsonString);
- } catch (JsonProcessingException e) {
- if(LOGGER.isWarnEnabled()){
- LOGGER.warn("update json string:" + jsonString + " to object:" + object + " error.", e);
- }
- } catch (IOException e) {
- if(LOGGER.isWarnEnabled()){
- LOGGER.warn("update json string:" + jsonString + " to object:" + object + " error.", e);
- }
- }
- return null;
- }
- /**
- * 輸出JSONP格式數據.
- */
- public String toJsonP(String functionName, Object object) {
- return toJson(new JSONPObject(functionName, object));
- }
- /**
- * 設定是否使用Enum的toString函數來讀寫Enum,
- * 為False時時使用Enum的name()函數來讀寫Enum, 默認為False.
- * 注意本函數一定要在Mapper創建後, 所有的讀寫動作之前調用.
- */
- public JsonMapper enableEnumUseToString() {
- this.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
- this.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
- return this;
- }
- /**
- * 支持使用Jaxb的Annotation,使得POJO上的annotation不用与Jackson耦合。
- * 默认会先查找jaxb的annotation,如果找不到再找jackson的。
- */
- public JsonMapper enableJaxbAnnotation() {
- JaxbAnnotationModule module = new JaxbAnnotationModule();
- this.registerModule(module);
- return this;
- }
- /**
- * 允许单引号
- * 允许不带引号的字段名称
- */
- public JsonMapper enableSimple() {
- this.configure(Feature.ALLOW_SINGLE_QUOTES, true);
- this.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
- return this;
- }
- /**
- * 取出Mapper做进一步的设置或使用其他序列化API.
- */
- public ObjectMapper getMapper() {
- return this;
- }
- /**
- * 对象转换为JSON字符串
- * @param object
- * @return
- */
- public static String toJsonString(Object object){
- return JsonMapper.getInstance().toJson(object);
- }
- /**
- * JSON字符串转换为对象
- * @param jsonString
- * @param clazz
- * @return
- */
- public static <T> T fromJsonString(String jsonString, Class<T> clazz){
- return JsonMapper.getInstance().fromJson(jsonString, clazz);
- }
- /**
- * 将obj对象转换成 class类型的对象
- * @param obj
- * @param clazz
- * @return
- */
- public static <T> T parseObject(Object obj, Class<T> clazz){
- return JSON.parseObject(JSON.toJSONString(obj), clazz);
- }
- }