redis單節點操作封裝-功能更新
阿新 • • 發佈:2019-01-04
博主曾與之前分享了兩篇文章,一篇關於redis單節點資料庫在lunix上的安裝,一篇為基於redis單節點資料庫的操作封裝。
本文基於前文redis單點快取資料庫操作封裝,新增redis服務功能。
檔案結構
RedisUtils.java——redis工具類,初始化配置
RedisService.java——redis服務類,提供多種redis的操作的封裝
redis-maven座標
<!-- redis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.0</version> </dependency>
所需依賴包commons-pool2-maven座標
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.4.2</version>
</dependency>
日誌類依賴maven座標
RedisUtil.java<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.6.6</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>1.7.25</version> </dependency>
package com.es.redis; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; /** * @author Anson * Copyright by EasyShare 2017 * * All right reserved * * Created on 2017年6月25日 下午4:12:56 * * redis工具類 */ public final class RedisUtil { /** Redis伺服器IP */ private static String ADDR; /** Redis的埠號 */ private static int PORT; /** 訪問密碼 */ private static String AUTH; /** 可用連線例項的最大數目,預設值為8<br> * 如果賦值為-1,則表示不限制;如果pool已經分配了maxActive個jedis例項,則此時pool的狀態為exhausted(耗盡) */ private static int MAX_ACTIVE; /** 控制一個pool最多有多少個狀態為idle(空閒的)的jedis例項,預設值也是8 */ private static int MAX_IDLE; /** 等待可用連線的最大時間,單位毫秒,預設值為-1,表示永不超時。如果超過等待時間,則直接丟擲JedisConnectionException */ private static int MAX_WAIT; /** 嘗試建立連線的最大等待時間 */ private static int TIMEOUT; /** 在borrow一個jedis例項時,是否提前進行validate操作;如果為true,則得到的jedis例項均是可用的 */ private static boolean TEST_ON_BORROW; /** redis連線池物件 */ private static JedisPool jedisPool = null; /** 日誌 */ private static Logger logger=LoggerFactory.getLogger(RedisUtil.class.getName()); /** * 初始化Redis連線池 */ static { try { //載入引數 loadProperty(); } catch (Exception e) { e.printStackTrace(); } } /** * 載入redis配置引數 */ private final static void loadProperty() { Properties prop=new Properties(); try { prop.load(new FileInputStream(new File(Thread.currentThread().getContextClassLoader().getResource("").getPath()+"redis.properties"))); ADDR=prop.getProperty("ADDR").trim(); PORT=Integer.parseInt(prop.getProperty("PORT").trim()); AUTH=prop.getProperty("AUTH"); MAX_ACTIVE=Integer.parseInt(prop.getProperty("MAX_ACTIVE").trim()); MAX_IDLE=Integer.parseInt(prop.getProperty("MAX_IDLE").trim()); MAX_WAIT=Integer.parseInt(prop.getProperty("MAX_WAIT").trim()); TIMEOUT=Integer.parseInt(prop.getProperty("TIMEOUT").trim()); TEST_ON_BORROW=prop.getProperty("TEST_ON_BORROW").trim().toLowerCase().equals("true"); logger.info("redis引數載入成功," + "引數:ADDR="+ADDR+" PORT="+PORT+" AUTH="+AUTH+ "MAX_ACTIVE="+MAX_ACTIVE+" MAX_IDLE="+MAX_IDLE+" MAX_WAIT="+MAX_WAIT+" TIMEOUT="+TIMEOUT+" TEST_ON_BORROW="+TEST_ON_BORROW); } catch (IOException e) { e.printStackTrace(); } } /** * 建立redis池 */ private final static void initJedisPool() { try { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(MAX_ACTIVE); config.setMaxIdle(MAX_IDLE); config.setMaxWaitMillis(MAX_WAIT); config.setTestOnBorrow(TEST_ON_BORROW); jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH); // logger.info(jedisPool!=null?"redis池建立成功":"redis池建立失敗,位置:"+RedisUtil.class.getName()); logger.info(jedisPool!=null?"redis連線池建立成功":""); }catch(Exception e) { logger.error("第一次嘗試建立jedis連線池錯誤,位置:"+RedisUtil.class.getName()); try { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxIdle(MAX_ACTIVE); config.setMaxIdle(MAX_IDLE); config.setMaxWaitMillis(MAX_WAIT); config.setTestOnBorrow(TEST_ON_BORROW); jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH); logger.info(jedisPool!=null?"redis連線池建立成功":""); }catch(Exception e1) { logger.error("第二次嘗試建立jedis連線池錯誤,位置:"+RedisUtil.class.getName()); } } } /** * 多執行緒下同步初始化 */ private synchronized static void loadPool() { if(jedisPool==null) { initJedisPool(); } } /** * 同步獲取Jedis例項,通過引數index選擇不同資料庫<br> * 可選資料庫編號index範圍:0-16<br> * @param index * 資料庫編號 * @return * Jedis - redis操作例項 */ public synchronized static Jedis getJedis(int index){ if(jedisPool==null) { //未建立連線池是建立連線池 loadPool(); } Jedis jedis=null; try { if (jedisPool != null) { jedis= jedisPool.getResource(); //選擇資料庫 jedis.select(index); } } catch (Exception e) { logger.info("獲取redis物件失敗,位置:"+RedisUtil.class.getName()); e.printStackTrace(); } return jedis; } /** * 釋放jedis資源 * @param jedis * Jedis - redis操作例項 */ public synchronized static void close(final Jedis jedis){ if (jedis!=null) { jedis.close(); } } }
RedisService.java
package com.es.redis;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
/**
* @author Anson
* Copyright by EasyShare 2017
*
* All right reserved
*
* Created on 2017年6月25日 下午4:12:38
*
* redis服務類
*/
public class RedisService {
private static Logger logger=LoggerFactory.getLogger(RedisService.class.getName());
/** 資料庫編號,預設為0號資料庫 **/
private static int INDEX=0;
/**
* 獲取當前使用的資料庫編號,若未設定,則預設為0號<br>
* @return
* index-資料庫編號
*/
public synchronized static int index() {
return INDEX;
}
/**
* 設定所需使用的資料庫編號,若不設定,則預設為0號<br>
* 可使用的資料庫編號index範圍:0-16<br>
* @param index
* 資料庫編號
*/
public synchronized static void select(int index) {
INDEX = index;
}
/**
* 通過key值獲取redis中的value,獲取後釋放連結
* @param key
* String - 鍵
* @return
* object - 值
*/
public synchronized static Object get(String key)
{
Jedis jedis=null;
byte[] value=null;
Object obj=null;
jedis=RedisUtil.getJedis(INDEX);
value=jedis.get(key.getBytes());
if(value!=null)
{
obj=deSerialize(value);
}
RedisUtil.close(jedis);
return obj;
}
/**
* 快取一個物件,key存在則覆蓋
* @param key
* String - 需儲存的的鍵
* @param value
* Object - 需儲存的值
* @return
* boolean
*/
public synchronized static boolean set(String key, Object obj)
{
Jedis jedis=null;
String code=null;
jedis=RedisUtil.getJedis(INDEX);
code=jedis.set(key.getBytes(), serialize(obj));
RedisUtil.close(jedis);
return code.toLowerCase().equals("ok");
}
/**
* 快取帶有存活時間的Object,key存在則覆蓋
* @param key
* String - 快取物件的鍵
* @param obj
* Object - 快取物件
* @param expire
* int - 存活時間,單位秒
* @return
* boolean
*/
public synchronized static boolean set(String key, Object obj, int expire)
{
Jedis jedis=null;
String code=null;
jedis=RedisUtil.getJedis(INDEX);
code=jedis.set(key.getBytes(), serialize(obj));
jedis.expire(key.getBytes(), expire);//key存活s
RedisUtil.close(jedis);
return code.toLowerCase().equals("ok");
}
/**
* 快取一個鍵值對,key-value,key存在則覆蓋
* @param key
* String - 鍵
* @param value
* String - 值
* @return
* boolean
*/
public synchronized static boolean set(String key, String value)
{
Jedis jedis=null;
String code=null;
jedis=RedisUtil.getJedis(INDEX);
code=jedis.set(key.getBytes(), serialize(value));
RedisUtil.close(jedis);
return code.toLowerCase().equals("ok");
}
/**
* 快取一個鍵值對,key-value,並設定快取存活時間,key存在則覆蓋
* @param key
* String - 鍵
* @param value
* String - 值
* @param expire
* int - 存活時間,秒
* @return
* boolean
*/
public synchronized static boolean set(String key, String value, int expire)
{
Jedis jedis=null;
String code=null;
jedis=RedisUtil.getJedis(INDEX);
code=jedis.set(key.getBytes(), serialize(value));
jedis.expire(key.getBytes(), expire);//key存活時間
RedisUtil.close(jedis);
return code.toLowerCase().equals("ok");
}
/**
* redis批量寫入
* 事物操作
* 當前進行的事物操作,若對應的資料被其他程序修改,則該事物將被打斷
* @param objects
* Map<String, Object> - Map鍵值對組成的待儲存物件
* @return
* boolean
*/
public synchronized static boolean tset(Map<String, Object> objects)
{
Jedis jedis=null;
List<Object> result=null;
jedis=RedisUtil.getJedis(INDEX);
Transaction t=null;
try {
t=jedis.multi();
for(Entry<String, Object> entry:objects.entrySet())
{
//監視資料
t.watch(entry.getKey().getBytes());
//儲存資料
t.set(entry.getKey().getBytes(), serialize(entry.getValue()));
}
result=t.exec();
} catch (Exception e) {
//回滾操作
t.discard();
logger.error("Redis事物操作被打斷,位置:{},丟擲異常:{}", RedisService.class.getName(),e);
}
RedisUtil.close(jedis);
return result!=null;
}
/**
* redis批量寫入
* 事物操作
* 當前進行的事物操作,若對應的資料被其他程序修改,則該事物將被打斷
* @param objects
* Map<String, Object> - Map鍵值對組成的待儲存物件
* @param expire
* 資料失效時間
* @return
* boolean
*/
public synchronized static boolean tset(Map<String, Object> objects, int expire)
{
Jedis jedis=null;
List<Object> result=null;
jedis=RedisUtil.getJedis(INDEX);
Transaction t=null;
try {
t=jedis.multi();
for(Entry<String, Object> entry:objects.entrySet())
{
//監視資料
t.watch(entry.getKey().getBytes());
//儲存資料
t.set(entry.getKey().getBytes(), serialize(entry.getValue()));
t.expire(entry.getKey().getBytes(), expire);//每個key存活expire秒
}
result=t.exec();
} catch (Exception e) {
//回滾操作
t.discard();
logger.error("Redis事物操作被打斷,位置:{},丟擲異常:{}", RedisService.class.getName(),e);
}
RedisUtil.close(jedis);
return result!=null;
}
/**
* 模糊檢索key
* @param pattern
* key匹配模板
* @return
* 匹配的key集合
*/
public synchronized static Set<String> keys(String pattern)
{
Jedis jedis=null;
jedis=RedisUtil.getJedis(INDEX);
Set<String> keys=new HashSet<String>();
keys=jedis.keys(pattern);
RedisUtil.close(jedis);
return keys;
}
/**
* 刪除key對應的快取資料
* @param key
* String-可變數量的key
* @return
* boolean
*/
public synchronized static long del(String ... keys)
{
Jedis jedis=null;
long code=0;
jedis=RedisUtil.getJedis(INDEX);
code=jedis.del(keys);
RedisUtil.close(jedis);
return code;
}
/**
* 批量刪除操作
* @param key
* String - 鍵
* @return
* boolean
*/
public synchronized static long delbat(String key)
{
Jedis jedis=null;
long code=0;
jedis=RedisUtil.getJedis(INDEX);
Set<String> keySet=jedis.keys(key+"*");
if(keySet!=null&&keySet.size()>0)
{
//將獲得的keys轉換成陣列型別
String[] keys=new String[keySet.size()];
keySet.toArray(keys);
code=jedis.del(keys);
}
RedisUtil.close(jedis);
return code;
}
/**
* 清空資料庫
* @param isClearAll
* 是否清空所有資料庫<br>
* <p>false-清空當前使用的資料庫,預設為0</p>
* @return
* true||false
*/
public synchronized static boolean clear(boolean isClearAll)
{
Jedis jedis=null;
String code=null;
jedis=RedisUtil.getJedis(INDEX);
if(isClearAll)
{
code=jedis.flushAll();
}else
{
code = jedis.flushDB();
}
RedisUtil.close(jedis);
return code.toLowerCase().equals("ok");
}
/**
* 批量獲取操作
* @param key
* String - 鍵
* @return
* List<Object> - 獲取的物件列表
*/
public synchronized static List<Object> getbat(String key)
{
Jedis jedis=null;
List<Object> objects=new ArrayList<Object>();
Object object=null;
jedis=RedisUtil.getJedis(INDEX);
Set<String> keySet=jedis.keys(key+"*");
RedisUtil.close(jedis);
if(keySet!=null&&keySet.size()>0)
{
Iterator<String> it=keySet.iterator();
while(it.hasNext())
{
String item=it.next();
object=get(item);
if(object!=null)
{
objects.add(object);
}
}
}
return objects;
}
/**
* 序列化儲存物件
* @param obj
* Object - 待序列化物件
* @return
* byte[] - 序列化結果
*/
private synchronized static byte[] serialize(Object obj)
{
byte[] serialObj=null;
ObjectOutputStream oos=null;
ByteArrayOutputStream baos=null;
try {
baos=new ByteArrayOutputStream();
oos=new ObjectOutputStream(baos);
oos.writeObject(obj);
serialObj=baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}finally
{
try {
if(baos!=null)
{
baos.close();
}
if(oos!=null)
{
oos.close();
}
} catch (IOException e) {
logger.error("釋放序列化資源失敗,位置:{},排除異常:{}",RedisService.class.getName(),e);
}
}
return serialObj;
}
/**
* 反序列化物件
* @param serialObj
* byte[] - 序列化物件
* @return
* Object - 反序列化結果
*/
private synchronized static Object deSerialize(byte[] serialObj)
{
Object object=null;
ObjectInputStream ois=null;
ByteArrayInputStream bais=null;
try {
if(serialObj!=null&&serialObj.length>0)
{
bais=new ByteArrayInputStream(serialObj);
ois=new ObjectInputStream(bais);
object=ois.readObject();
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally
{
try {
if(bais!=null)
{
bais.close();
}
if(ois!=null)
{
ois.close();
}
} catch (IOException e) {
logger.error("釋放反序列化資源失敗,位置:{},丟擲異常:{}",RedisService.class.getName(),e);
}
}
return object;
}
}