参考: 一级缓存二级缓存的获取与更新顺序(一)
简单封装Ehcache与RedisTemplate模版
通常使用一二级缓存时,必须保持一二级缓存数据数据与数据库中数据保持一致 ;此时可以简单封装下,一二级缓存的相关接口,便于我们同步数据操作;
Ehcache封装
package org.jd.auth.data.security.server.base;import lombok.extern.slf4j.Slf4j;
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;import javax.annotation.Resource;
import java.util.Map;/*** ehcache缓存服务组件:* 这样重写Ehcache缓存组件的目的在于使用一级缓存和二级缓存时,便于及时同步一二级缓存的数据* @Author: yh19166*/
@Slf4j
@Component
public class SSOEhcacheService {@Resource@Qualifier("ehCacheManager")private CacheManager cacheManager;/*** @param cacheName 为ehcache.xml文件中配置缓存的名称* @return*/public Cache<String, Object> getCache(String cacheName) {Cache cache = this.cacheManager.getCache(cacheName, String.class, Object.class);if (ObjectUtils.isEmpty(cache)) { // 避免了Optional对象为Optional.empty()空对象;ObjectUtils.isEmpty(方法源代码已经作了判断)log.error("SSOEhcacheService.getCache.cacheName[{}] is not exit", cacheName);}return cache;}/*** 根据cacheKey获取对应的值** @param cacheName 配置文件中配置缓存的名称* @param cacheKey 缓存Key* @return {@link Object}*/public Object get(String cacheName, String cacheKey) {Cache<String, Object> cache = getCache(cacheName);if (ObjectUtils.isEmpty(cache)) {log.error("SSOEhcacheService.do.get method,[{}] is not exit", cacheName);return null;}return cache.get(cacheKey);}/*** @param cacheName 配置文件中配置缓存的名称* @param cacheKey 缓存key* @param value 缓存值*/public void put(String cacheName, String cacheKey, Object value) {Cache<String, Object> cache = getCache(cacheName);if (ObjectUtils.isEmpty(cache)) {log.error("SSOEhcacheService.do.put method,[{}] is not exit", cacheName);return;}cache.put(cacheKey, value);}/*** @param cacheName 配置文件中配置缓存的名称* @param value 缓存值*/public void putAll(String cacheName, Map<String, Object> value) {Cache<String, Object> cache = getCache(cacheName);if (ObjectUtils.isEmpty(cache)) {log.error("SSOEhcacheService.do.putAll method,[{}] is not exit", cacheName);return;}cache.putAll(value);}/*** 判断缓存key是否存在** @param cacheName 配置文件中配置缓存的名称* @param key 缓存key* @return {@link Boolean}*/public boolean exist(String cacheName, String key) {Cache<String, Object> cache = getCache(cacheName);if (ObjectUtils.isEmpty(cache)) {log.error("SSOEhcacheService.do.exist method,[{}] is not exit", cacheName);return false;}return cache.containsKey(key);}/*** 删除指定key的缓存** @param cacheName 配置文件中配置缓存的名称* @param key 缓存key*/public void evict(String cacheName, String key) {Cache<String, Object> cache = getCache(cacheName);if (ObjectUtils.isEmpty(cache)) {log.error("SSOEhcacheService.do.evict method,[{}] is not exit", cacheName);return;}cache.remove(key);}
}
RedisTemplate模版简单封装
package org.jd.auth.data.security.server.base;import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.TimeUnit;/*** Redis通常作为二级缓存* Redis缓存对: spring-boot-starter-data-redis的模版(RedisTemplate)的进一步封装:* @Author: yh19166*/
@Slf4j
@Component
public class SSORedisService {@Resourceprivate RedisTemplate<Serializable, Object> redisTemplate;/*** 批量删除对应的value** @param keys*/public void remove(String... keys) {for (String key : keys) {remove(key);}}/*** 正则批量删除key 例:h?llo matches hello, hallo** @param pattern*/public void removePattern(String pattern) {Set<Serializable> keys = redisTemplate.keys(pattern);if (!keys.isEmpty()) {redisTemplate.delete(keys);}}/*** 正则获取多个缓存key 例:h?llo matches hello, hallo** @param pattern*/public Set<Serializable> patternKeys(String pattern) {return redisTemplate.keys(pattern);}/*** 正则key获取多个缓存** @param pattern* @return 返回Set >-String 集合*/public Set<String> patternKeysIsStr(String pattern) {Set<Serializable> keys = redisTemplate.keys(pattern);Set<String> dataSet = new HashSet<>();for (Serializable obj : keys) {dataSet.add(obj.toString());}return dataSet;}/*** 删除对应的value** @param key*/public void remove(String key) {if (exists(key)) {redisTemplate.delete(key);}}/*** 判断缓存中是否有对应的value** @param key* @return*/public boolean exists(String key) {return redisTemplate.hasKey(key);}/*** 设置key的过期时间 单位(秒)** @param key* @param expireTime* @return boolean*/public boolean setKeyExpire(String key, Long expireTime) {return redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);}/*** 读取缓存** @param key* @return*/public Object getObject(String key) {Object result = null;ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();result = operations.get(key);return result;}/*** 写入缓存** @param key* @param value* @return*/public boolean setObject(String key, Object value) {boolean result = false;try {ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();operations.set(key, value);result = true;} catch (Exception e) {log.warn("setObject 返回异常 " + e.getMessage());}return result;}/*** 写入缓存设置并设置时间 时间单位(秒)** @param key* @param value* @return*/public boolean setObjectAndExpire(String key, Object value, Long expireTime) {boolean result = false;try {ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();operations.set(key, value);redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);result = true;} catch (Exception e) {log.warn("setObjectAndExpire 返回异常 " + e.getMessage());}return result;}/*** 缓存List数据 右侧入栈** @param key 缓存的键值* @param dataList 待缓存的List数据* @return 缓存的对象*/public boolean setList(String key, List<Object> dataList) {boolean result = false;try {ListOperations<Serializable, Object> listOperation = redisTemplate.opsForList();if (null != dataList) {int size = dataList.size();for (int i = 0; i < size; i++) {listOperation.rightPush(key, dataList.get(i));}}result = true;} catch (Exception e) {log.warn("setList 返回异常 " + e.getMessage());}return result;}/*** 缓存List数据 右侧入栈 并设置过期时间 单位(秒)** @param key 缓存的键值* @param dataList 待缓存的List数据* @return 缓存的对象*/public boolean setListAndExpire(String key, List<Object> dataList, Long expireTime) {boolean result = false;try {ListOperations<Serializable, Object> listOperation = redisTemplate.opsForList();if (null != dataList) {int size = dataList.size();for (int i = 0; i < size; i++) {listOperation.rightPush(key, dataList.get(i));}}redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);result = true;} catch (Exception e) {log.warn("setListAndExpire 返回异常 " + e.getMessage());}return result;}/*** 获得缓存的list对象** @param key 缓存的键值* @return 缓存键值对应的数据*/public List<Object> getList(String key) {ListOperations<Serializable, Object> listOperation = redisTemplate.opsForList();return listOperation.range(key, 0, -1);}/*** 获得缓存的list对象 出栈的方式获取数据 左侧出栈** @param key 缓存的键值* @return 缓存键值对应的数据*/public List<Object> getListPop(String key) {List<Object> dataList = new ArrayList<>();ListOperations<Serializable, Object> listOperation = redisTemplate.opsForList();Long size = listOperation.size(key);for (int i = 0; i < size; i++) {dataList.add(listOperation.leftPop(key));}return dataList;}/*** 缓存Set** @param key 缓存键值* @param dataSet 缓存的数据* @return 缓存数据的对象*/public boolean setSet(String key, Set<Object> dataSet) {boolean result = false;try {BoundSetOperations<Serializable, Object> setOperation = redisTemplate.boundSetOps(key);Iterator<Object> it = dataSet.iterator();while (it.hasNext()) {setOperation.add(it.next());}result = true;} catch (Exception e) {log.warn("setSet 返回异常 " + e.getMessage());}return result;}/*** 缓存Set并设置失效时间 单位(秒)** @param key 缓存键值* @param dataSet 缓存的数据* @return 缓存数据的对象*/public boolean setSetAndExpire(String key, Set<Object> dataSet, Long expireTime) {boolean result = false;try {BoundSetOperations<Serializable, Object> setOperation = redisTemplate.boundSetOps(key);Iterator<Object> it = dataSet.iterator();while (it.hasNext()) {setOperation.add(it.next());}redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);result = true;} catch (Exception e) {log.warn("setSetAndExpire 返回异常 " + e.getMessage());}return result;}/*** 获得缓存的set** @param key* @param* @return*/public Set<Object> getSet(String key) {BoundSetOperations<Serializable, Object> operation = redisTemplate.boundSetOps(key);return operation.members();}/*** 获得缓存的set 已出栈方式获取** @param key* @param* @return*/public Set<Object> getSetPop(String key) {Set<Object> dataSet = new HashSet<>();BoundSetOperations<Serializable, Object> operation = redisTemplate.boundSetOps(key);Long size = operation.size();for (int i = 0; i < size; i++) {dataSet.add(operation.pop());}return dataSet;}/*** 缓存Hash(字典,哈希表)** @param key* @param dataMap* @return*/public boolean setMap(String key, Map<String, Object> dataMap) {boolean result = false;try {HashOperations<Serializable, Object, Object> hashOperations = redisTemplate.opsForHash();if (null != dataMap) {for (Map.Entry<String, Object> entry : dataMap.entrySet()) {hashOperations.put(key, entry.getKey(), entry.getValue());}}result = true;} catch (Exception e) {log.warn("setMap 返回异常 " + e.getMessage());}return result;}/*** 缓存Hash(字典,哈希表)并设置过期时间 单位(秒)** @param key* @param dataMap* @return*/public boolean setMapAndExpire(String key, Map<String, Object> dataMap, Long expireTime) {boolean result = false;try {HashOperations<Serializable, Object, Object> hashOperations = redisTemplate.opsForHash();if (null != dataMap) {for (Map.Entry<String, Object> entry : dataMap.entrySet()) {hashOperations.put(key, entry.getKey(), entry.getValue());}}redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);result = true;} catch (Exception e) {log.warn("setMapAndExpire 返回异常 " + e.getMessage());}return result;}/*** 缓存Hash(字典,哈希表)并设置过期时间 单位(秒) 值类型为 Map<String, String>** @param key* @param dataMap* @return*/public boolean setStrMapAndExpire(String key, Map<String, String> dataMap, Long expireTime) {boolean result = false;try {HashOperations<Serializable, Object, Object> hashOperations = redisTemplate.opsForHash();if (null != dataMap) {for (Map.Entry<String, String> entry : dataMap.entrySet()) {hashOperations.put(key, entry.getKey(), entry.getValue());}}redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);result = true;} catch (Exception e) {log.warn("setMapAndExpire 返回异常 " + e.getMessage());}return result;}/*** 获得缓存的Hash(字典,哈希表)** @param key* @param* @return*/public Map<String, Object> getMap(String key) {HashOperations<Serializable, String, Object> hashOperations = redisTemplate.opsForHash();return hashOperations.entries(key);}/*** 根据key和hashKey获得缓存Hash中的值** @param key* @param* @return String*/public String getMapByHashKey(String key, String hashKey) {HashOperations<Serializable, String, Object> hashOperations = redisTemplate.opsForHash();return (String) hashOperations.get(key, hashKey);}/*** 缓存有序Set 默认score为添加的顺序** @param key 缓存键值* @param dataSet 缓存的数据* @return 缓存数据的对象*/public boolean setZSet(String key, Set<Object> dataSet) {boolean result = false;try {BoundZSetOperations<Serializable, Object> setOperation = redisTemplate.boundZSetOps(key);int size = dataSet.size();Iterator<Object> it = dataSet.iterator();while (it.hasNext()) {setOperation.add(it.next(), --size);}result = true;} catch (Exception e) {log.warn("setZSet 返回异常 " + e.getMessage());}return result;}/*** 缓存有序Set 并添加失效时间单位(秒) 默认score为添加的顺序** @param key 缓存键值* @param dataSet 缓存的数据* @return 缓存数据的对象*/public boolean setZSetAndExpire(String key, Set<Object> dataSet, Long expireTime) {boolean result = false;try {BoundZSetOperations<Serializable, Object> setOperation = redisTemplate.boundZSetOps(key);int size = dataSet.size();Iterator<Object> it = dataSet.iterator();while (it.hasNext()) {if (size > 0) {setOperation.add(it.next(), size--);}}redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);result = true;} catch (Exception e) {log.warn("setZSetAndExpire 返回异常 " + e.getMessage());}return result;}/*** 缓存有序Set** @param key* @return 缓存数据的对象*/public Set<Object> getZSetRange(String key) {BoundZSetOperations<Serializable, Object> operation = redisTemplate.boundZSetOps(key);return operation.range(0, -1);}/*** 根据key 返回该key的存活时间 单位(秒)** @param key 缓存键值* @return key 的存活时间 单位(秒)*/public Long getExpire(String key) {return redisTemplate.getExpire(key, TimeUnit.SECONDS);}/*** 根据key 设置时间 单位(秒)** @param key 缓存键值* @return boolean*/public Boolean setUpExpire(String key, Long expireTime) {return redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);}/*** 清空redis 所有数据** @return 成功返回 ok*/public String flushDb() {return (String) redisTemplate.execute(new RedisCallback<Object>() {@Overridepublic String doInRedis(RedisConnection connection) {connection.flushDb();return "ok";}});}/*** @return 查看redis里有多少数据*/public long dbSize() {return (long) redisTemplate.execute(new RedisCallback<Object>() {@Overridepublic Long doInRedis(RedisConnection connection) {return connection.dbSize();}});}/*** 检查是否连接成功** @return 成功则返回 PONG 失败什么都不会留下*/public String ping() {return (String) redisTemplate.execute(new RedisCallback<Object>() {@Overridepublic String doInRedis(RedisConnection connection) {return connection.ping();}});}/*** 生成自增长* @param key* @return {@link Long}*/public Long createAutoNo(String key) {return redisTemplate.opsForValue().increment(key, 1);}
}