Redis
1.配置Jedis參數(shù)
redis.clients.jedis.JedisPoolConfig
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大能夠保持idel狀態(tài)的對象數(shù) -->
<property name="maxIdle" value="${jedis.maxIdle}" />
<!-- 最大分配的對象數(shù) 高版本中用來替換maxWait參數(shù) -->
<property name="maxWaitMillis" value="${jedis.maxWait}" />
<!-- 最大分配的對象數(shù) -->
<property name="maxTotal" value="${jedis.maxTotal}" />
<!-- 當(dāng)調(diào)用borrowObject獲取jedis實(shí)例方法時(shí),是否進(jìn)行有效性檢查(ping) -->
<property name="testOnBorrow" value="true" />
<!------------------------------ 通常配置以上參數(shù),以下參數(shù)可選 ---------------------------------->
<!-- 最大能獲得jedis實(shí)例的個(gè)數(shù),高版本中刪除 -->
<property name="maxActive" value="${jedis.maxActive}"/>
<!-- pool中的jedis實(shí)例被用完時(shí)的策略
WHEN_EXHAUSTED_FAIL 表示無jedis實(shí)例時(shí),直接拋出NoSuchElementException;
WHEN_EXHAUSTED_BLOCK 表示阻塞住,超時(shí)拋出JedisConnectionException;
WHEN_EXHAUSTED_GROW 表示自動(dòng)增長,新建一個(gè)jedis實(shí)例,不受maxTotal限制 -->
<property name="whenExhaustedAction" value="${jedis.whenExhaustedAction}">
<!-- borrowObject返回jedis實(shí)例時(shí)采用FIFO策略還是LIFO策略 默認(rèn)為true(LIFO策略),false為FIFO -->
<property name="lifo" value="${jedis.lifo}">
</bean>
2.配置redis池
redis.clients.jedis.JedisPool
<bean id="jedisPool0" class="redis.clients.jedis.JedisPool">
<!-- jedis配置 -->
<constructor-arg name="poolConfig" ref="jedisPoolConfig" />
<!-- jedis服務(wù)器地址 -->
<constructor-arg name="host" value="${jedis.host}" />
<!-- jedis服務(wù)器端口 -->
<constructor-arg name="port" value="${jedis.port}" type="int" />
<!-- 指定在空閑多少秒后斷開連接 -->
<constructor-arg name="timeout" value="${jedis.timeout}" type="int" />
<!-- jedis服務(wù)器密碼 -->
<constructor-arg name="password" value="#{'${jedis.pwd}'!=''?'${jedis.pwd}':null}" />
<!-- jedis數(shù)據(jù)庫index -->
<constructor-arg name="database" value="${jedis.db.index0}" type="int" />
</bean>
<!-- 配置多個(gè)redis池 -->
<bean id="jedisPool1" class="redis.clients.jedis.JedisPool">
<constructor-arg name="poolConfig" ref="jedisPoolConfig" />
<constructor-arg name="host" value="${jedis.host}" />
<constructor-arg name="port" value="${jedis.port}" type="int" />
<constructor-arg name="timeout" value="${jedis.timeout}" type="int" />
<constructor-arg name="password" value="#{'${jedis.pwd}'!=''?'${jedis.pwd}':null}" />
<constructor-arg name="database" value="${jedis.db.index1}" type="int" />
</bean>
3.配置工具map
<bean id="jedisPoolsMap" class="java.util.HashMap">
<constructor-arg>
<map>
<entry key="${jedis.db.index0}" value-ref="jedisPool0"/>
<entry key="${jedis.db.index1}" value-ref="jedisPool1"/>
</map>
</constructor-arg>
</bean>
4.jedis的使用
文末會附上jedis工具類的java代碼
5.服務(wù)器查看redis的鍵值
ps -ef | grep redis-server #查看redis信息
netstat -ano | grep -6379 #按端口查找
redis-cli -h 127.0.0.1 -p 6379 --raw #登陸redis服務(wù)器,-h 主機(jī)ip , -p 端口號 , -a 密碼 --raw按中文原有方式輸出
KEYS #返回所有關(guān)鍵字
GET key #根據(jù)關(guān)鍵字獲取字符串類型的值
HEYS key #返回哈希表key中所有的域
HGET key field #返回哈希表key中給定域的值
HMGET key field[filed....] #返回哈希表key中給定的多個(gè)域的值
DEL key[key...] #刪除給定的一個(gè)或多個(gè)key
Quit
*************************************************************華麗的分割線*************************************************************
Memcache
1.配置IO線程池
<bean id="memcacheResource" class="com.whalin.MemCached.SockIOPool"
factory-method="getInstance" init-method="initialize" destroy-method="shutDown">
<!-- 構(gòu)造函數(shù)參數(shù) -->
<constructor-arg><value>memcacheResource</value></constructor-arg>
<!-- memcache服務(wù)器的地址,可以設(shè)置多個(gè)服務(wù)器 -->
<property name="servers"><list><value>${memcacheURL}</value></list></property>
<!-- 每個(gè)服務(wù)器初始連接數(shù) -->
<property name="initConn"><value>10</value></property>
<!-- 每個(gè)服務(wù)器最小連接數(shù) -->
<property name="minConn"><value>10</value></property>
<!-- 每個(gè)服務(wù)器最大連接數(shù) -->
<property name="maxConn"><value>150</value></property>
<!-- 每隔5秒維護(hù)一次連接數(shù) -->
<property name="maintSleep"><value>5000</value></property>
<!-- 最大空閑時(shí)間 -->
<property name="maxIdle"><value>600000</value></property>
<!-- 禁用nagle算法 -->
<property name="nagle"><value>false</value></property>
<!-- TCP連接讀取超時(shí) 3秒鐘 -->
<property name="socketTO"><value>3000</value></property>
</bean>
2.配置客戶端和包裝類
<bean id="mccResource" class="com.whalin.MemCached.MemCachedClient">
<constructor-arg>
<value>memcacheResource</value>
</constructor-arg>
</bean>
<!-- 自定義封裝的包裝類,文末會附上示例代碼 -->
<bean id="cacheWrapper" class="com.revo.eeducation.server.memcached.MemCacheWrapper">
<constructor-arg>
<ref bean="mccResource" />
</constructor-arg>
</bean>
3.服務(wù)器查看緩存
get key[key...] #返回儲存在鍵中的值
set key 0 900 9 #設(shè)置鍵值對 key鍵 flags 一般為0 exptime 緩存時(shí)效(秒)bytes 在緩存中存儲的字節(jié)
memcache #設(shè)置存儲的值 必須換行,且長度要跟設(shè)置的字節(jié)數(shù)一致,不然會報(bào)錯(cuò)CLIENT_ERROR bad data chunk
replace、append、prepend的語法跟set一致
stats #統(tǒng)計(jì)命令
Redis 和 memcache 比較
內(nèi)存使用效率:用簡單的key-value存儲,memcache的效率更好,而如果redis使用Hash結(jié)構(gòu)來存儲key-value,則redis的效率要高于memcache
性能方面: 在小數(shù)據(jù)量存儲時(shí),redis要高于memcache;在超過100K的數(shù)據(jù)中,memcache的性能更優(yōu)
另外: redis對復(fù)雜數(shù)據(jù)提供的支持更多,而memcache可以設(shè)置多個(gè)服務(wù)器
JedisUtil.java
@Component
public class JedisUtil {
private static final Logger LOGGER = Logger.getLogger(JedisUtil.class);
/**默認(rèn)數(shù)據(jù)庫*/
public static final int DB_DEFAULT = 0;
/**數(shù)據(jù)庫緩存*/
public static final int DB_SQL = 1;
/**jedis連接池對象名前綴*/
public static final String JEDIS_POOL_PREFIX = "jedisPool";
@Autowired
private Map<String,JedisPool> jedisPoolsMap;
/**
* 獲取jedis對象
* @param database 數(shù)據(jù)庫
* @return Jedis對象
*/
private Jedis getJedis(int database){
if(MapUtils.isEmpty(jedisPoolsMap)){
LOGGER.info("=============================注入連接池jedisPoolsMap失敗=========================================");
}
return jedisPoolsMap.get(JEDIS_POOL_PREFIX+database).getResource();
}
/**
* 檢測redis是否OK
* @return ok返回<code>true</code>
*/
public boolean isOK(){
Boolean bl = Boolean.FALSE;
Jedis jedis = getJedis(DB_DEFAULT);
if(!CommonUtils.isEmpty(jedis)){
bl = Boolean.TRUE;
}
jedis.close();
return bl;
}
/**
* 設(shè)置緩存
* @param database 數(shù)據(jù)庫
* @param key 緩存KEY
* @param value 緩存值
* @return Status code reply
*/
public String set(int databse,String key,String value){
Jedis jedis = getJedis(databse);
String val = jedis.set(key, value);
jedis.close();
return val;
}
/**
* 設(shè)置緩存
* @param key 緩存KEY
* @param value 緩存值
* @return Status code reply
*/
public String set(String key,String value){
return set(DB_DEFAULT, key, value);
}
/**
* 設(shè)置緩存
* @param database 數(shù)據(jù)庫
* @param key 緩存KEY
* @param value 緩存值
* @return Status code reply
*/
public String set(int databse,String key,Serializable value){
Jedis jedis = getJedis(databse);
String val = jedis.set(key.getBytes(), SerializableUtil.toByteArray(value));
jedis.close();
return val;
}
/**
* 設(shè)置緩存
* @param key 緩存KEY
* @param value 緩存值
* @return Status code reply
*/
public String set(String key,Serializable value){
return set(DB_DEFAULT, key, value);
}
/**
* 設(shè)置帶有時(shí)間長度的緩存
* @param database 數(shù)據(jù)庫
* @param key 緩存KEY
* @param value 緩存值
* @param time 緩存時(shí)間 ,毫秒
* @return Status code reply
*/
public String set(int database,String key,String value,long time){
Jedis jedis = getJedis(database);
String nxxx = "NX";
if(jedis.exists(key)){
nxxx = "XX";
}
String val = jedis.set(key, value,nxxx,"PX",time);
jedis.close();
return val;
}
/**
* 設(shè)置帶有時(shí)間長度的緩存
* @param key 緩存KEY
* @param value 緩存值
* @param time 緩存時(shí)間 ,毫秒
* @return Status code reply
*/
public String set(String key,String value,long time){
return set(DB_DEFAULT, key, value, time);
}
/**
* 設(shè)置帶有時(shí)間長度的緩存
* @param database 數(shù)據(jù)庫
* @param key 緩存KEY
* @param value 緩存值
* @param time 緩存時(shí)間 ,毫秒
* @return Status code reply
*/
public String set(int database,String key,Serializable value,long time){
Jedis jedis = getJedis(database);
byte[] byteKey = SerializableUtil.toByteArray(key);
String nxxx = "NX";
if(jedis.exists(byteKey)){
nxxx = "XX";
}
byte[] nxxxByte = nxxx.getBytes();
byte[] epxxByte = "PX".getBytes();
String val = jedis.set(byteKey, SerializableUtil.toByteArray(value),nxxxByte,epxxByte,time);
jedis.close();
return val;
}
/**
* 設(shè)置帶有時(shí)間長度的緩存
* @param key 緩存KEY
* @param value 緩存值
* @param time 緩存時(shí)間 ,毫秒
* @return Status code reply
*/
public String set(String key,Serializable value,long time){
return set(DB_DEFAULT, key, value, time);
}
/**
* 檢查redis中是否包含key
* @param database 數(shù)據(jù)庫
* @param key redis key
* @return true if key is exists
*/
public boolean containsKey(int database,String key){
Jedis jedis = getJedis(database);
boolean result = jedis.exists(key);
jedis.close();
return result;
}
/**
* 檢查redis中是否包含key
* @param key redis key
* @return true if key is exists
*/
public boolean containsKey(String key){
return containsKey(DB_DEFAULT, key);
}
/**
* 調(diào)用Redis的LPUSH命令
* @param database 數(shù)據(jù)庫
* @param key redis key
* @param val redis value
* @return true if key is exists
*/
public Long lpush(int database,String key,String... val){
Long ret = -1L;
Jedis jedis = getJedis(database);
ret = jedis.lpush(key, val);
jedis.close();
return ret;
}
/**
* 調(diào)用Redis的LPUSH命令
* @param key redis key
* @param val redis value
* @return true if key is exists
*/
public Long lpush(String key,String... val){
return lpush(DB_DEFAULT, key, val);
}
/**
* 調(diào)用Redis的hmset 將map保存到redis緩存中
* @param database 數(shù)據(jù)庫
* @param key
* @param map
*/
public void hmset(int database,String key,Map<String, String> map){
Jedis jedis = getJedis(database);
jedis.hmset(key, map);
jedis.close();
}
/**
* 調(diào)用Redis的hmset 將map保存到redis緩存中
* @param key
* @param map
*/
public void hmset(String key,Map<String, String> map){
hmset(DB_DEFAULT, key, map);
}
/**
* 調(diào)用Redis的hmget 獲取對應(yīng)key保存map中存儲的fields對應(yīng)的數(shù)據(jù)
* @param key
* @param fields
* @return
*/
public List<String> hmget(int database,String key,String... fields){
Jedis jedis = getJedis(database);
List<String> list = jedis.hmget(key, fields);
jedis.close();
return list;
}
/**
* 調(diào)用Redis的hmget 獲取對應(yīng)key保存map中存儲的fields對應(yīng)的數(shù)據(jù)
* @param key
* @param fields
* @return
*/
public List<String> hmget(String key,String... fields){
return hmget(DB_DEFAULT, key, fields);
}
/**
* 調(diào)用Redis的hmget 獲取對應(yīng)key保存map中存儲的fields對應(yīng)的數(shù)據(jù)
* @param database 數(shù)據(jù)庫
* @param key 緩存的KEY
* @param cls 需要轉(zhuǎn)換的對象
* @param fields map的key
* @return
*/
public <T> List<T> hmget(int database,String key,Class<T> cls,String... fields){
Jedis jedis = getJedis(database);
List<String> list = jedis.hmget(key, fields);
if(CollectionUtils.isNotEmpty(list) && !list.contains(null)){
String retStr = Joiner.on(",").join(list);
retStr = StringUtils.appendIfMissing(retStr, "]", "]");
retStr = StringUtils.prependIfMissing(retStr, "[", "[");
jedis.close();
return JSON.parseArray(retStr, cls);
}
jedis.close();
return null;
}
/**
* 調(diào)用Redis的hmget 獲取對應(yīng)key保存map中存儲的fields對應(yīng)的數(shù)據(jù)
* @param key 緩存的KEY
* @param cls 需要轉(zhuǎn)換的對象
* @param fields map的key
* @return
*/
public <T> List<T> hmget(String key,Class<T> cls,String... fields){
return hmget(DB_DEFAULT, key, cls, fields);
}
/**
* 調(diào)用Redis的hmget 獲取對應(yīng)key保存map中存儲的fields對應(yīng)的數(shù)據(jù)
* @param database 數(shù)據(jù)庫
* @param key 緩存的KEY
* @param type 需要轉(zhuǎn)換的對象
* @param fields map的key
* @return
*/
public <T> List<T> hmget(int database,String key,Type type,String... fields){
Jedis jedis = getJedis(database);
List<String> list = jedis.hmget(key, fields);
if(CollectionUtils.isNotEmpty(list) && !list.contains(null)){
String retStr = Joiner.on(",").join(list);
retStr = StringUtils.appendIfMissing(retStr, "]", "]");
retStr = StringUtils.prependIfMissing(retStr, "[", "[");
jedis.close();
return JSON.parseObject(retStr, type);
}
jedis.close();
return null;
}
/**
* 調(diào)用Redis的hmget 獲取對應(yīng)key保存map中存儲的fields對應(yīng)的數(shù)據(jù)
* @param key 緩存的KEY
* @param type 需要轉(zhuǎn)換的對象
* @param fields map的key
* @return
*/
public <T> List<T> hmget(String key,Type type,String... fields){
return hmget(DB_DEFAULT, key, type, fields);
}
/**
* 調(diào)用Redis的hmget 獲取全部數(shù)據(jù)
* @param database 數(shù)據(jù)庫
* @param key
* @return
*/
public Map<String,String> hgetAll(int dababase,String key){
Jedis jedis = getJedis(dababase);
Map<String,String> map = jedis.hgetAll(key);
jedis.close();
return map;
}
/**
* 調(diào)用Redis的hmget 獲取全部數(shù)據(jù)
* @param key
* @return
*/
public Map<String,String> hgetAll(String key){
return hgetAll(DB_DEFAULT, key);
}
/**
* 調(diào)用Redis的hmget 獲取全部value數(shù)據(jù)
* @param key
* @return
*/
public List<Object> hgetAllValue2Object(int database,String key){
Map<String, String> map = hgetAll(database,key);
List<Object> valList = new ArrayList<>();
if(map != null){
for (Iterator<String> iterator = map.values().iterator(); iterator.hasNext();) {
String val = iterator.next();
if(JsonUtils.isJSONArray(val)){
JSONArray jsonArray = JSON.parseArray(val);
if(!jsonArray.isEmpty()){
for (Object json : jsonArray) {
valList.add(json);
}
}
}else if(JsonUtils.isJSONObject(val)){
valList.add(JSON.parse(val));
}else{
valList.add(val);
}
}
}
return valList;
}
/**
* 調(diào)用Redis的hmget 獲取全部value數(shù)據(jù)
* @param key
* @return
*/
public List<Object> hgetAllValue2Object(String key){
return hgetAllValue2Object(DB_DEFAULT, key);
}
/**
* 調(diào)用Redis的hmget 獲取全部value數(shù)據(jù)
* @param key
* @return
*/
public String hgetAllValue2Str(String key){
List<Object> valList = hgetAllValue2Object(key);
return CollectionUtils.isEmpty(valList) ? StringUtils.EMPTY : JSON.toJSONString(valList);
}
/**
* 調(diào)用Redis的hmget 獲取全部value數(shù)據(jù),并轉(zhuǎn)換為對象
* @param key
* @param cls
* @return
*/
public <T> List<T> hgetAllValue(String key,Class<T> cls){
List<Object> valList = hgetAllValue2Object(key);
return JSON.parseArray(JSON.toJSONString(valList),cls);
}
/**
* 調(diào)用Redis的hmget 獲取全部value數(shù)據(jù),并轉(zhuǎn)換為對象
* @param key
* @param cls
* @return
*/
public <T> T hgetAllValue(String key,Type type){
List<Object> valList = hgetAllValue2Object(key);
return JSON.parseObject(JSON.toJSONString(valList),type);
}
/**
* 調(diào)用Redis的hmget 獲取全部key數(shù)據(jù)
* @param key
* @return
*/
public List<String> hgetAllKey2Str(String key){
Map<String, String> map = hgetAll(key);
List<String> ret = new ArrayList<>();
ret.addAll(map.keySet());
return ret;
}
/**
* 調(diào)用Redis的hmget 獲取對應(yīng)key保存map中存儲的fields對應(yīng)的數(shù)據(jù)
* @param database 數(shù)據(jù)庫
* @param key
* @param fields
* @return
*/
public String hmget4Single(int database,String key,String field){
String ret = StringUtils.EMPTY;
Jedis jedis = getJedis(database);
List<String> list = jedis.hmget(key, field);
if(CollectionUtils.isNotEmpty(list)){
ret = list.get(0);
}
jedis.close();
return ret;
}
/**
* 調(diào)用Redis的hmget 獲取對應(yīng)key保存map中存儲的fields對應(yīng)的數(shù)據(jù)
* @param key
* @param fields
* @return
*/
public String hmget4Single(String key,String field){
return hmget4Single(DB_DEFAULT, key, field);
}
/**
* 調(diào)用Redis的hmget 獲取對應(yīng)key保存map中存儲的fields對應(yīng)的數(shù)據(jù)
* @param database 數(shù)據(jù)庫
* @param key
* @param fields
* @param cls 需要轉(zhuǎn)換的對象
* @return
*/
public <T> T hmget4Single(int database,String key,String field,Class<T> cls){
String ret = StringUtils.EMPTY;
Jedis jedis = getJedis(database);
List<String> list = jedis.hmget(key, field);
if(CollectionUtils.isNotEmpty(list)){
ret = list.get(0);
}
jedis.close();
return StringUtils.isNotEmpty(ret) ? JSON.parseObject(ret, cls) : null;
}
/**
* 調(diào)用Redis的hmget 獲取對應(yīng)key保存map中存儲的fields對應(yīng)的數(shù)據(jù)
* @param key
* @param fields
* @param cls 需要轉(zhuǎn)換的對象
* @return
*/
public <T> T hmget4Single(String key,String field,Class<T> cls){
return hmget4Single(DB_DEFAULT, key, field, cls);
}
/**
* 調(diào)用Redis的HSET命令-散列
* @param database 數(shù)據(jù)庫
* @param key redis key
* @param val redis value
* @return true if key is exists
*/
public Long hset(int database,String key,String field,String value){
Long ret = -1L;
Jedis jedis = getJedis(database);
ret = jedis.hset(key, field, value);
jedis.close();
return ret;
}
/**
* 調(diào)用Redis的HSET命令-散列
* @param key redis key
* @param val redis value
* @return true if key is exists
*/
public Long hset(String key,String field,String value){
return hset(DB_DEFAULT, key, field, value);
}
/**
* 根據(jù)key前綴獲取所有匹配的value
* @param database 數(shù)據(jù)庫
* @param prefixKey key 前綴
* @return List
*/
public List<String> getAllElementByPrefixKey(int database,String prefixKey){
Jedis jedis = getJedis(database);
List<String> result = new ArrayList<>();
Set<String> values = jedis.keys(prefixKey + "*");
for (String value : values){
result.add(value);
}
jedis.close();
return result;
}
/**
* 根據(jù)key前綴獲取所有匹配的value
* @param prefixKey key 前綴
* @return List
*/
public List<String> getAllElementByPrefixKey(String prefixKey){
return getAllElementByPrefixKey(DB_DEFAULT, prefixKey);
}
/**
* 根據(jù)KEY獲取緩存數(shù)據(jù)
* @param database 數(shù)據(jù)庫
* @param key 緩存KEY
* @return 獲取的緩存值
*/
public String get(int database,String key){
Jedis jedis = getJedis(database);
String val = jedis.get(key);
jedis.close();
return val;
}
/**
* 根據(jù)KEY獲取緩存數(shù)據(jù)
* @param key 緩存KEY
* @return 獲取的緩存值
*/
public String get(String key){
return get(DB_DEFAULT, key);
}
/**
* 根據(jù)KEY獲取緩存數(shù)據(jù)
* @param key 緩存KEY
* @return 獲取的緩存值
*/
@SuppressWarnings("unchecked")
public <T> T getSerializable(int database,String key){
Jedis jedis = getJedis(database);
byte[] byteKey = SerializableUtil.toByteArray(key);
if(!jedis.exists(byteKey)){
jedis.close();
return null;
}
Serializable val = SerializableUtil.toObject(jedis.get(byteKey));
jedis.close();
return (T) val;
}
/**
* 根據(jù)KEY獲取緩存數(shù)據(jù)
* @param key 緩存KEY
* @return 獲取的緩存值
*/
public <T> T getSerializable(String key){
return getSerializable(DB_DEFAULT, key);
}
/**
* 根據(jù)KEY獲取緩存數(shù)據(jù)對象
* @param key 緩存KEY
* @param clasz 需要轉(zhuǎn)換的對象
* @return 從緩存中獲取的對象
*/
public <T> T get(int database,String key,Class<T> clasz){
Jedis jedis = getJedis(database);
String val = jedis.get(key);
jedis.close();
return StringUtils.isEmpty(val) ? null : JSON.parseObject(val, clasz);
}
/**
* 根據(jù)KEY獲取緩存數(shù)據(jù)對象
* @param key 緩存KEY
* @param clasz 需要轉(zhuǎn)換的對象
* @return 從緩存中獲取的對象
*/
public <T> T get(String key,Class<T> clasz){
return get(DB_DEFAULT, key, clasz);
}
/**
* 根據(jù)KEY獲取緩存數(shù)據(jù)并轉(zhuǎn)換成List
* @param key
* @return string集合
*/
public List<String> getRedisList(String key){
String value = get(key);
if(StringUtils.isEmpty(value)){
return new ArrayList<>();
}
@SuppressWarnings("unchecked")
List<String> list = JSON.parseObject(value, List.class);
return list;
}
/**
* 根據(jù)key刪除client的緩存
* @param database 數(shù)據(jù)庫
* @param key
*/
public void remove(int database,String key){
Jedis jedis = getJedis(database);
if(jedis.exists(key)){
Long del = jedis.del(key);
}
jedis.close();
}
/**
* 根據(jù)key刪除client的緩存
* @param key
*/
public void remove(String key){
remove(DB_DEFAULT, key);
}
/**
* 根據(jù)前綴刪除緩存
* @param database 數(shù)據(jù)庫
* @param regex 正則字符串
*/
public void removePattern(int database,String regex){
Jedis jedis = getJedis(database);
Set<String> keys = jedis.keys(regex);
if(!CommonUtils.isEmpty(keys)){
jedis.del((String[])keys.toArray(new String[keys.size()]));
}
jedis.close();
}
/**
* 根據(jù)前綴刪除緩存
* @param regex 正則字符串
*/
public void removePattern(String regex){
removePattern(DB_DEFAULT, regex);
}
/**
* 根據(jù)前綴刪除緩存
* @param regex 正則字符串
*/
public void removeSerializePattern(int database,String regex){
Jedis jedis = getJedis(database);
Set<byte[]> keys = jedis.keys(regex.getBytes());
if(!CommonUtils.isEmpty(keys)){
byte[][] keyByteArray = new byte[keys.size()][];
int i = 0;
for (Iterator<byte[]> iterator = keys.iterator(); iterator.hasNext();) {
byte[] bs = (byte[]) iterator.next();
keyByteArray[i++] = bs;
}
jedis.del(keyByteArray);
}
jedis.close();
}
/**
* 根據(jù)前綴刪除緩存
* @param regex 正則字符串
*/
public void removeSerializePattern(String regex){
removeSerializePattern(DB_DEFAULT, regex);
}
/**
* 向redis中添加字符串集合
* @param database 數(shù)據(jù)庫
* @param key redis中key
* @param valueList 字符串集合
*/
public void addListElement(int database,String key,List<String> valueList){
if (CollectionUtils.isEmpty(valueList)){
return;
}
Jedis jedis = getJedis(database);
jedis.rpush(key, valueList.toArray(new String[valueList.size()]));
jedis.close();
}
/**
* 向redis中添加字符串集合
* @param key redis中key
* @param valueList 字符串集合
*/
public void addListElement(String key,List<String> valueList){
addListElement(DB_DEFAULT, key, valueList);
}
/**
* 向redis中添加字符串
* @param database 數(shù)據(jù)庫
* @param key redis中key
* @param strings 字符串
*/
public void addStrElement(int database,String key, String... strings) {
if (strings.length <= 0) {
return;
}
Jedis jedis = getJedis(database);
jedis.rpush(key, strings);
jedis.close();
}
/**
* 向redis中添加字符串
* @param key redis中key
* @param strings 字符串
*/
public void addStrElement(String key, String... strings) {
addStrElement(DB_DEFAULT, key, strings);
}
/**
* 根據(jù)key獲取list所有元素
* @param key redis中key
* @return List
*/
public List<String> getListByKey(int database,String key){
Jedis jedis = getJedis(database);
List<String> result = jedis.lrange(key, 0l, jedis.llen(key) - 1);
jedis.close();
return result;
}
/**
* 根據(jù)key獲取list所有元素
* @param key redis中key
* @return List
*/
public List<String> getListByKey(String key){
return getListByKey(DB_DEFAULT, key);
}
/**
* 取出并刪除名稱為key的list首元素
* @param key redis中key
* @return list中首元素
*/
public String removeListElement(int database,String key){
Jedis jedis = getJedis(database);
String result = jedis.lpop(key);
jedis.close();
return result;
}
/**
* 取出并刪除名稱為key的list首元素
* @param key redis中key
* @return list中首元素
*/
public String removeListElement(String key){
return removeListElement(DB_DEFAULT, key);
}
/**
* 獲取名稱為key的list size
* @param database 數(shù)據(jù)庫
* @param key redis中key
* @return size
*/
public long getListSizeByKey(int database,String key){
Jedis jedis = getJedis(database);
long size = jedis.llen(key);
jedis.close();
return size;
}
/**
* 獲取名稱為key的list size
* @param key redis中key
* @return size
*/
public long getListSizeByKey(String key){
return getListSizeByKey(DB_DEFAULT, key);
}
/**
* 獲取redis中名稱key的list中count個(gè)元素并刪除(從頭至尾刪除)
* @param database 數(shù)據(jù)庫
* @param key redis中key
* @param count 需刪除的元素個(gè)數(shù)
* @return list,刪除的元素集合,count必須大于零小于等于list size,否則返回empty list
*/
public List<String> removeList(int database,String key,int count){
List<String> result = new ArrayList<>();
if (count <= 0){
return result;
}
Jedis jedis = getJedis(database);
long listSize = jedis.llen(key);
if (count > listSize){
count = (int)listSize;
}
for (int x = 0,i = count; x < i; x++){
result.add(jedis.lpop(key));
}
jedis.close();
return result;
}
/**
* 獲取redis中名稱key的list中count個(gè)元素并刪除(從頭至尾刪除)
* @param key redis中key
* @param count 需刪除的元素個(gè)數(shù)
* @return list,刪除的元素集合,count必須大于零小于等于list size,否則返回empty list
*/
public List<String> removeList(String key,int count){
return removeList(DB_DEFAULT, key, count);
}
/**
* 獲取redis中名稱key的MAP中 key為${mapKey}的value值
* @param jedisKey
* @param mapKey
* @return List<String>
*/
public List<String> getMapValByKey(int database,String jedisKey, String mapKey) {
Jedis jedis = getJedis(database);
List<String> list = jedis.hmget(jedisKey, mapKey);
jedis.close();
return list;
}
/**
* 獲取redis中名稱key的MAP中 key為${mapKey}的value值
* @param jedisKey
* @param mapKey
* @return List<String>
*/
public List<String> getMapValByKey(String jedisKey, String mapKey) {
return getMapValByKey(DB_DEFAULT, jedisKey, mapKey);
}
/**
* 檢查key在redis中是否存在
* @param key
* @return 存在返回<code>true</code>,否則返回<code>false</code>
*/
public boolean exists(int database,String key) {
Jedis jedis = getJedis(database);
Boolean exists = jedis.exists(key);
jedis.close();
return exists;
}
/**
* 檢查key在redis中是否存在
* @param key
* @return 存在返回<code>true</code>,否則返回<code>false</code>
*/
public boolean exists(String key) {
return exists(DB_DEFAULT, key);
}
/**
* 設(shè)置 list
* @param database 數(shù)據(jù)庫
* @param <T>
* @param key
* @param value
*/
public <T> void setList(int database,String key, List<T> list) {
Jedis jedis = getJedis(database);
try {
jedis.set(key.getBytes(), ObjectSerializableUtil.serialize(list));
} catch (Exception e) {
LOGGER.error("Set key error : " + e);
}finally{
jedis.close();
}
}
/**
* 設(shè)置 list
* @param <T>
* @param key
* @param value
*/
public <T> void setList(String key, List<T> list) {
setList(DB_DEFAULT, key, list);
}
/**
* 獲取list
* @param database 數(shù)據(jù)庫
* @param <T>
* @param key
* @return list
*/
@SuppressWarnings("unchecked")
public <T> List<T> getList(int database,String key) {
if(StringUtils.isEmpty(key)){
LOGGER.error("jedis-傳入的KEY為空");
return null;
}
Jedis jedis = getJedis(database);
if (jedis == null || !jedis.exists(key.getBytes())) {
jedis.close();
return null;
}
byte[] in = jedis.get(key.getBytes());
List<T> list = (List<T>) ObjectSerializableUtil.deserialize(in);
jedis.close();
return list;
}
/**
* 獲取list
* @param <T>
* @param key
* @return list
*/
public <T> List<T> getList(String key) {
return getList(DB_DEFAULT, key);
}
}
MemCacheWrapper.java
/**
* 包裝 {@link MemCachedClient},集中處理緩存錯(cuò)誤不影響業(yè)務(wù)流程
*
*
*/
public class MemCacheWrapper
{
private static ServerLogger logger = new ServerLogger(MemCacheWrapper.class);
private MemCachedClient client;
/**
* 是否可寫(默認(rèn)為可寫)
*/
private boolean writable = true;
private String[] servers;
public MemCacheWrapper(MemCachedClient client)
{
this.client = client;
try
{
com.whalin.MemCached.SockIOPool sockIOPool = BeanHolder.getBean("memcacheResource");
this.servers = sockIOPool.getServers();
String localIp = InetAddress.getLocalHost().getHostAddress();
boolean matched = false;
for (String server : this.servers)
{
//只有添加在里面的ip才會開啟可寫模式;
if (server.contains("localhost") || server.contains("127.0.0.1") || server.contains(localIp))
{
matched = true;
break;
}
}
this.writable = matched;
}
catch (Exception e)
{
logger.error("判斷memcached是否可寫失敗!", e);
}
}
public <T> Map<String, T> getMulti(Class<T> type, String... keys)
{
return getMap(type, keys);
}
@SuppressWarnings("unchecked")
private <T> Map<String, T> getMap(Class<T> type, String... keys)
{
Map<String, Object> map = client.getMulti(keys);
if (map == null)
{
// 總是返回一個(gè)Map防止程序出現(xiàn)空指針異常
return new HashMap<String, T>();
}
Iterator<Entry<String, Object>> it = map.entrySet().iterator();
while (it.hasNext())// 類型轉(zhuǎn)換檢查
{
Entry<String, Object> entry = it.next();
if (entry.getValue() == null)
{
continue;
}
entry.setValue(castAs(type, entry.getKey(), entry.getValue()));
if (entry.getValue() == null)
{
it.remove();
}
}
return (Map<String, T>)map;
}
public <T> T get(Class<T> type, String key)
{
Object t = client.get(key);
return castAs(type, key, t);
}
@SuppressWarnings("unchecked")
public <T> T[] getMultiArray(Class<T> type, String... keys)
{
Object[] values = client.getMultiArray(keys);
if (values == null)
{
return (T[])Array.newInstance(type, 0);
}
T[] arr = (T[])Array.newInstance(type, values.length);
for (int i = 0; i < values.length; i++)
{
arr[i] = castAs(type, null, values[i]);
}
return arr;
}
/**
* 增加一個(gè)指定鍵的計(jì)數(shù)器+1
*
* @param key
* @return
*/
public long incr(String key)
{
return client.incr(key);
}
/**
* 增加一個(gè)指定鍵的計(jì)數(shù)器+value
*
* @param key
* @param value
* @return
*/
public long incr(String key, long value)
{
return client.incr(key, value);
}
public long decr(String key)
{
return client.decr(key);
}
public long decr(String key, long value)
{
return client.decr(key, value);
}
public boolean delete(String key)
{
return client.delete(key);
}
@SuppressWarnings("deprecation")
public boolean delete(String key, Date expiry)
{
return client.delete(key, expiry);
}
public boolean set(String key, Object value)
{
if (!writable)
{
return false;
}
if (value == null)
{
Throwable t = new Throwable("null value to cache TraceStack");
logger.error("set a null value to memcache with key[" + key + "] ,See follow invoke trace", t);
return false;
}
return client.set(key, value);
}
public boolean set(String key, Object value, Date expire)
{
if (!writable)
{
return false;
}
if (value == null)
{
Throwable t = new Throwable("null value to cache TraceStack");
logger.error("set a null value to memcache with key[" + key + "] ,See follow invoke trace", t);
return false;
}
return client.set(key, value, expire);
}
/**
* 執(zhí)行stats命令,返回緩存的當(dāng)前狀態(tài)
*
* @return
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public Map<String, Map<String, String>> stats()
{
Map map = client.stats();
if (map == null)
{
return new HashMap<String, Map<String, String>>();
}
return map;
}
/**
* 在所有的Memcached服務(wù)端執(zhí)行緩存清除動(dòng)作
*
* Will return true only if succeeds in clearing all servers.
*
* @return success true/false
*/
public boolean flushAll()
{
return client.flushAll();
}
/**
* 在指定的Memcached服務(wù)端執(zhí)行緩存清除動(dòng)作 Will return true only if succeeds in clearing all servers. If pass in null, then will
* try to flush all servers.
*
* @param servers optional array of host(s) to flush (host:port)
* @return success true/false
*/
public boolean flushAll(String[] servers)
{
return client.flushAll(servers);
}
/**
* 進(jìn)行類型轉(zhuǎn)換同時(shí)處理轉(zhuǎn)換異常
*
* @param type
* @param value
* @return
*/
private <T> T castAs(Class<T> type, String key, Object value)
{
if (value == null)
{
return null;
}
try
{
T t = type.cast(value);
return t;
}
catch (ClassCastException ignoreMe)
{
StringBuilder errMsg = new StringBuilder("+++ incorrect cache type[");
errMsg.append(value.getClass().getName())
.append("] with key[" + key + "], value [")
.append(value)
.append("]");
errMsg.append(",expect type [").append(type.getName()).append("]");
logger.error(errMsg, ignoreMe);
}
return null;
}
public boolean isWritable()
{
return writable;
}
public void setWritable(boolean writable)
{
this.writable = writable;
}
public String[] getServers()
{
return servers;
}
}