参考: 一级缓存二级缓存的获取与更新顺序(一)
简单封装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 {
@Resource
private 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>() {
@Override
public String doInRedis(RedisConnection connection) {
connection.flushDb();
return "ok";
}
});
}
/**
* @return 查看redis里有多少数据
*/
public long dbSize() {
return (long) redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Long doInRedis(RedisConnection connection) {
return connection.dbSize();
}
});
}
/**
* 检查是否连接成功
*
* @return 成功则返回 PONG 失败什么都不会留下
*/
public String ping() {
return (String) redisTemplate.execute(new RedisCallback<Object>() {
@Override
public String doInRedis(RedisConnection connection) {
return connection.ping();
}
});
}
/**
* 生成自增长
* @param key
* @return {@link Long}
*/
public Long createAutoNo(String key) {
return redisTemplate.opsForValue().increment(key, 1);
}
}