转:https://www.cnblogs.com/JAYIT/p/5647924.html
所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。
所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。
缓存主要可分为二大类:
一、通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式;
二、内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查.
代码如下:package lhm.hcy.guge.frameset.cache;import java.util.*;//Description: 管理缓存//可扩展的功能:当chche到内存溢出时必须清除掉最早期的一些缓存对象,这就要求对每个缓存对象保存创建时间public class CacheManager {private static HashMap cacheMap = new HashMap();//单实例构造方法private CacheManager() {super();}//获取布尔值的缓存public static boolean getSimpleFlag(String key){try{return (Boolean) cacheMap.get(key);}catch(NullPointerException e){return false;}}public static long getServerStartdt(String key){try {return (Long)cacheMap.get(key);} catch (Exception ex) {return 0;}}//设置布尔值的缓存public synchronized static boolean setSimpleFlag(String key,boolean flag){if (flag && getSimpleFlag(key)) {//假如为真不允许被覆盖return false;}else{cacheMap.put(key, flag);return true;}}public synchronized static boolean setSimpleFlag(String key,long serverbegrundt){if (cacheMap.get(key) == null) {cacheMap.put(key,serverbegrundt);return true;}else{return false;}}//得到缓存。同步静态方法private synchronized static Cache getCache(String key) {return (Cache) cacheMap.get(key);}//判断是否存在一个缓存private synchronized static boolean hasCache(String key) {return cacheMap.containsKey(key);}//清除所有缓存public synchronized static void clearAll() {cacheMap.clear();}//清除某一类特定缓存,通过遍历HASHMAP下的所有对象,来判断它的KEY与传入的TYPE是否匹配public synchronized static void clearAll(String type) {Iterator i = cacheMap.entrySet().iterator();String key;ArrayList arr = new ArrayList();try {while (i.hasNext()) {java.util.Map.Entry entry = (java.util.Map.Entry) i.next();key = (String) entry.getKey();if (key.startsWith(type)) { //如果匹配则删除掉arr.add(key);}}for (int k = 0; k < arr.size(); k++) {clearOnly(arr.get(k));}} catch (Exception ex) {ex.printStackTrace();}}//清除指定的缓存public synchronized static void clearOnly(String key) {cacheMap.remove(key);}//载入缓存public synchronized static void putCache(String key, Cache obj) {cacheMap.put(key, obj);}//获取缓存信息public static Cache getCacheInfo(String key) {if (hasCache(key)) {Cache cache = getCache(key);if (cacheExpired(cache)) { //调用判断是否终止方法cache.setExpired(true);}return cache;}elsereturn null;}//载入缓存信息public static void putCacheInfo(String key, Cache obj, long dt,boolean expired) {Cache cache = new Cache();cache.setKey(key);cache.setTimeOut(dt + System.currentTimeMillis()); //设置多久后更新缓存cache.setValue(obj);cache.setExpired(expired); //缓存默认载入时,终止状态为FALSEcacheMap.put(key, cache);}//重写载入缓存信息方法public static void putCacheInfo(String key,Cache obj,long dt){Cache cache = new Cache();cache.setKey(key);cache.setTimeOut(dt+System.currentTimeMillis());cache.setValue(obj);cache.setExpired(false);cacheMap.put(key,cache);}//判断缓存是否终止public static boolean cacheExpired(Cache cache) {if (null == cache) { //传入的缓存不存在return false;}long nowDt = System.currentTimeMillis(); //系统当前的毫秒数long cacheDt = cache.getTimeOut(); //缓存内的过期毫秒数if (cacheDt <= 0||cacheDt>nowDt) { //过期时间小于等于零时,或者过期时间大于当前时间时,则为FALSEreturn false;} else { //大于过期时间 即过期return true;}}//获取缓存中的大小public static int getCacheSize() {return cacheMap.size();}//获取指定的类型的大小public static int getCacheSize(String type) {int k = 0;Iterator i = cacheMap.entrySet().iterator();String key;try {while (i.hasNext()) {java.util.Map.Entry entry = (java.util.Map.Entry) i.next();key = (String) entry.getKey();if (key.indexOf(type) != -1) { //如果匹配则删除掉k++;}}} catch (Exception ex) {ex.printStackTrace();}return k;}//获取缓存对象中的所有键值名称public static ArrayList getCacheAllkey() {ArrayList a = new ArrayList();try {Iterator i = cacheMap.entrySet().iterator();while (i.hasNext()) {java.util.Map.Entry entry = (java.util.Map.Entry) i.next();a.add((String) entry.getKey());}} catch (Exception ex) {} finally {return a;}}//获取缓存对象中指定类型 的键值名称public static ArrayList getCacheListkey(String type) {ArrayList a = new ArrayList();String key;try {Iterator i = cacheMap.entrySet().iterator();while (i.hasNext()) {java.util.Map.Entry entry = (java.util.Map.Entry) i.next();key = (String) entry.getKey();if (key.indexOf(type) != -1) {a.add(key);}}} catch (Exception ex) {} finally {return a;}}}package lhm.hcy.guge.frameset.cache;public class Cache {private String key;//缓存IDprivate Object value;//缓存数据private long timeOut;//更新时间private boolean expired; //是否终止public Cache() {super();}public Cache(String key, Object value, long timeOut, boolean expired) {this.key = key;this.value = value;this.timeOut = timeOut;this.expired = expired;}public String getKey() {return key;}public long getTimeOut() {return timeOut;}public Object getValue() {return value;}public void setKey(String string) {key = string;}public void setTimeOut(long l) {timeOut = l;}public void setValue(Object object) {value = object;}public boolean isExpired() {return expired;}public void setExpired(boolean b) {expired = b;}
}//测试类,
class Test {public static void main(String[] args) {System.out.println(CacheManager.getSimpleFlag("alksd"));
// CacheManager.putCache("abc", new Cache());
// CacheManager.putCache("def", new Cache());
// CacheManager.putCache("ccc", new Cache());
// CacheManager.clearOnly("");
// Cache c = new Cache();
// for (int i = 0; i < 10; i++) {
// CacheManager.putCache("" + i, c);
// }
// CacheManager.putCache("aaaaaaaa", c);
// CacheManager.putCache("abchcy;alskd", c);
// CacheManager.putCache("cccccccc", c);
// CacheManager.putCache("abcoqiwhcy", c);
// System.out.println("删除前的大小:"+CacheManager.getCacheSize());
// CacheManager.getCacheAllkey();
// CacheManager.clearAll("aaaa");
// System.out.println("删除后的大小:"+CacheManager.getCacheSize());
// CacheManager.getCacheAllkey();}
}
spring中的redis service实现package com.eshore.ismp.cache.redis;import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;@Service
public class RedisService {private static String redisCode = "utf-8";@Autowiredprivate RedisTemplate<String, String> redisTemplate;/*** 从指定的列表右边出队,添加到目的列表中** @param srckey* 源列表* @param dstkey* 目的列表* @return*/public String rpoppush(final String srckey, final String dstkey) {return redisTemplate.execute(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {try {return new String (connection.rPopLPush(srckey.getBytes(), dstkey.getBytes()), redisCode);} catch (UnsupportedEncodingException e) {e.printStackTrace();}return "";}});}/*** 获取指定列表的范围数据** @param key* 列表名* @param start* 开始位置* @param end* 结束位置* @return*/public List<String> lrange(final String key, final int start, final int end) {return redisTemplate.execute(new RedisCallback<List<String>>() {List<String> result = new ArrayList<String>();public List<String> doInRedis(RedisConnection connection)throws DataAccessException {List<byte[]> bytelist= connection.lRange(key.getBytes(), start, end);for (byte[] b : bytelist) {try {result.add(new String(b, redisCode));} catch (UnsupportedEncodingException e) {e.printStackTrace();}}return result;}});}/*** 从队列的左边取出一条数据** @param key* 列表名* @return*/public String lpop(final String key) {return redisTemplate.execute(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {byte[] result = connection.lPop(key.getBytes());if (result != null) {try {return new String (result , redisCode);} catch (UnsupportedEncodingException e) {e.printStackTrace();}}return "";}});}/*** 从队列的左边取出一条数据** @param key* 列表名* @return*/public List<?> lpop(final String key,final int size) {List<Object> list = redisTemplate.executePipelined(new RedisCallback<List<Object>>() {public List<Object> doInRedis(RedisConnection connection)throws DataAccessException {byte[] keyBytes = key.getBytes();for(int i =0 ; i< size; i++){connection.lPop(keyBytes);}return null;}});list.removeAll(Collections.singleton(null));return list;}/*** 从列表右边添加数据** @param key* 列表名* @param values* 数据* @return*/public long rpush(final String key, final String... values) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {long result = 0;for (String v : values) {result = connection.rPush(key.getBytes(), v.getBytes());}return result;}});}/*** 从列表右边添加数据** @param key* 列表名* @param values* 数据* @return*/public long rpush(final String key, final Collection<String> values) {return redisTemplate.opsForList().rightPushAll(key, values);}public int hmset(final String key, final Map<String,String> values) {try{redisTemplate.opsForHash().putAll(key, values);}catch(Exception e){e.printStackTrace();return -1;}return 0 ;}public String hget(final String key, final String field){Object obj =redisTemplate.opsForHash().get(key, field);return String.valueOf(obj);}public List<?> hkeys(final String key){return redisTemplate.execute(new RedisCallback<List<Object>>(){List<Object> list = new ArrayList<Object>();public List<Object> doInRedis(RedisConnection connection)throws DataAccessException {Set<byte[]> sets=connection.hKeys(key.getBytes());if(!sets.isEmpty()){for(byte[] b : sets){list.add(redisTemplate.getValueSerializer().deserialize(b).toString());}return list;}return null;}});}/*** 删除hash表中field*/public void hdel(final String key,final String field){redisTemplate.opsForHash().delete(key, field);}/*** 从列表右边添加数据,并且设置列表的存活时间** @param key* 列表名* @param liveTime* 存活时间(单位 秒)* @param values* 数据* @return*/public long rpush(final String key, final int liveTime, final String... values) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {long result = 0;for (String v : values) {connection.rPush(key.getBytes(), v.getBytes());}if (liveTime > 0) {connection.expire(key.getBytes(), liveTime);} return result;}});}/*** 从队列的右边取出一条数据** @param key* 列表名* @return*/public String rpop(final String key) {return redisTemplate.execute(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {byte[] result = connection.rPop(key.getBytes());if(result != null ){try {return new String (result, redisCode);} catch (UnsupportedEncodingException e) {e.printStackTrace();}}return "";}});}/*** 把一个值添加到对应列表中** @param key* 列表名* @param index* 添加的位置* @param value* 数据* @return*/public String lset(final String key, final long index, final String value) {return redisTemplate.execute(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {connection.lSet(key.getBytes(), index, value.getBytes());return "success";}});}/*** 把所有数据添加到一个列表中** @param key* 列表名* @param values* 数据* @return*/public long lpush(String key, String... values) {return this.lpush(key, 0, values);}/*** 把所有数据添加到一个列表中,并且设置列表的存活时间** @param key* 列表名* @param values* 数据* @param liveTime* 存活时间--单位(秒)* @return*/public long lpush(final String key,final int liveTime, final String... values) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {long result = 0;for (String v : values){result = connection.lPush(key.getBytes(), v.getBytes());}if (liveTime > 0) {connection.expire(key.getBytes(), liveTime);}return result;}});}/*** 返回列表的长度** @param key* @return*/public long llen(final String key) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {return connection.lLen(key.getBytes());}});}/*** 删除列表中对应值的元素** @param key* 列表名* @param count* 删除多少个相同的元素* @param value* 数据* @return*/public long lrem(final String key, final long count, final String value) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {return connection.lRem(key.getBytes(), count, value.getBytes());}});}/*** 通过keys批量删除** @param key*/public long del(final String... keys) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {long result = 0;for (String k : keys) {result = connection.del(k.getBytes());}return result;}});}/**** //DESC 删除单个key* @time: 2016年5月27日 上午9:00:36* @param key* @return* @throws*/public long del(final String key){return redisTemplate.execute(new RedisCallback<Long>(){@Overridepublic Long doInRedis(RedisConnection connection)throws DataAccessException {return connection.del(key.getBytes());}});}/*** 添加key value 并且设置存活时间(byte)** @param key* @param value* @param liveTime*/public void set(final byte[] key, final byte[] value, final long liveTime) {redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {connection.set(key, value);if (liveTime > 0) {connection.expire(key, liveTime);}return 1L;}});}/*** 添加key value 并且设置存活时间** @param key* @param value* @param liveTime* 单位秒*/public void set(String key, String value, long liveTime) {this.set(key.getBytes(), value.getBytes(), liveTime);}/*** 添加key value** @param key* @param value*/public void set(String key, String value) {this.set(key, value, 0L);}/*** 添加key value** @param key* @param value*/public void setMulti(final Map<String,String> map) {setMulti(map,0L);}/*** 添加key value** @param key* @param value*/public void setMulti(final Map<String,String> map,final long liveTime) {redisTemplate.executePipelined(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {Set<Map.Entry<String, String >> set = map.entrySet();for (Entry<String, String> entry : set) {connection.set(entry.getKey().getBytes(), entry.getValue().getBytes());if (liveTime > 0) {connection.expire(entry.getKey().getBytes(), liveTime);}}return null;}});}/*** 添加key value (字节)(序列化)** @param key* @param value*/public void set(byte[] key, byte[] value) {this.set(key, value, 0L);}/*** 获取redis value (String)** @param key* @return*/public String get(final String key) {return redisTemplate.execute(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {byte[] result = connection.get(key.getBytes());if (result != null) {try {return new String (result ,redisCode);} catch (UnsupportedEncodingException e) {e.printStackTrace();} }return "";}});}/*** 如果key不存在添加key value 并且设置存活时间(byte),当key已经存在时,就不做任何操作** @param key* @param value* @param liveTime*/public long setnx(final byte[] key, final byte[] value, final long liveTime) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {long result = 0l;boolean isSuccess = connection.setNX(key, value);if (isSuccess) {if (liveTime > 0) {connection.expire(key, liveTime);}result = 1l;}return result;}});}/*** 如果key不存在添加key value 并且设置存活时间,当key已经存在时,就不做任何操作** @param key* @param value* @param liveTime* 单位秒*/public long setnx(String key, String value, long liveTime) {return this.setnx(key.getBytes(), value.getBytes(), liveTime);}/*** 如果key不存在添加key value,当key已经存在时,就不做任何操作** @param key* @param value*/public long setnx(String key, String value) {return this.setnx(key, value, 0L);}/*** 如果key不存在添加key value (字节)(序列化),当key已经存在时,就不做任何操作** @param key* @param value*/public long setnx(byte[] key, byte[] value) {return this.setnx(key, value, 0L);}/*** 通过正则匹配keys** @param pattern* @return*/public Set<String> keys(final String pattern) {return redisTemplate.execute(new RedisCallback<Set<String>>() {public Set<String> doInRedis(RedisConnection connection)throws DataAccessException {Set<String> result = new HashSet<String>();Set<byte[]> data = connection.keys(pattern.getBytes());for(byte[] d : data){try {result.add(new String(d,redisCode));} catch (UnsupportedEncodingException e) {e.printStackTrace();}}return result;}});}/*** 检查key是否已经存在** @param key* @return*/public boolean exists(final String key) {return redisTemplate.execute(new RedisCallback<Boolean>() {public Boolean doInRedis(RedisConnection connection)throws DataAccessException {return connection.exists(key.getBytes());}});}/*** 清空redis 所有数据** @return*/public String flushDB() {return redisTemplate.execute(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {connection.flushDb();return "success";}});}/*** 查看redis里有多少数据*/public long dbSize() {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {return connection.dbSize();}});}/*** 检查是否连接成功** @return*/public String ping() {return redisTemplate.execute(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {return connection.ping();}});}/*** 设置key的生命周期** @param key* @param seconds* 单位(秒)* @return*/public boolean expire(final String key, final long seconds) {return redisTemplate.execute(new RedisCallback<Boolean>() {public Boolean doInRedis(RedisConnection connection)throws DataAccessException {return connection.expire(key.getBytes(), seconds);}});}/*** 自增长** @param key* @param length 增长步长* @return*/public long incr (final String key){return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {return connection.incr(key.getBytes());}});}/*** 自增长** @param key* @param length 增长步长* @return*/public long incrBy (final String key, final long len){return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {return connection.incrBy(key.getBytes(), len);}});}/*** 自增长** @param key* @param length 增长步长* @return*/public double incrBy (final String key, final double len){return redisTemplate.execute(new RedisCallback<Double>() {public Double doInRedis(RedisConnection connection)throws DataAccessException {return connection.incrBy(key.getBytes(), len);}});}public long eval(final String luaCommand) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection) throws DataAccessException {return connection.eval(luaCommand.getBytes(), null,0);}});}}缓存应用:package com.eshore.ismp.cache.processor;import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eshore.ismp.cache.redis.RedisService;
import com.eshore.ismp.common.entity.ResultInfo;/**** //DESC: 管理门户缓存接口* @author zzx* @date 2016年5月20日 上午11:50:25*/
@Service
public class AdminWebProcessor {private static final Logger logger = Logger.getLogger(AdminWebProcessor.class);private static final String ADMINWEB_USER = "ADMINWEB_USER_";private static final Long LIVETIME = 60*30L;@AutowiredRedisService redisService;public String put(JSONObject param){Long userId = param.getLong("user_id");String userInfo = param.getString("user_info");ResultInfo rs = new ResultInfo();if(userId==null || StringUtils.isEmpty(userInfo)){logger.error("参数错误");rs.setResult_code(2501);rs.setResult_detail("参数错误");return JSON.toJSONString(rs);}String key = ADMINWEB_USER+userId;redisService.set(key , userInfo,LIVETIME);rs.setResult_code(0);rs.setResult_detail("success");return JSON.toJSONString(rs);}public String get(JSONObject param){Long userId = param.getLong("user_id");String key = ADMINWEB_USER+userId;ResultInfo rs = new ResultInfo();String user = redisService.get(key);rs.setResult_code(0);rs.setResult_detail("success");rs.setResult_data(user);return JSON.toJSONString(rs);}public String delete(JSONObject param){Long userId = param.getLong("user_id");String key = ADMINWEB_USER+userId;ResultInfo rs = new ResultInfo();long isDel = redisService.del(key);rs.setResult_code(0);rs.setResult_detail("success");return JSON.toJSONString(rs);}}