Redis學習記錄(二)--使用Jedis連線
Redis學習記錄(二)--使用Jedis連線
標籤(空格分隔): javaWEB
在Java環境中連線Redis首選Jedis,因為Jedis封裝的特別好,所以連線對於開發者也就變得很簡單了,本文主要講述如何寫出優雅的Jedis連線程式碼.
1.設計模式分析
對於Jedis,有一個連線池JedisPool
,這個連線池管理著程式中的jedis示例,對於單機部署,每一次使用jedis都是去池中取出來連線池,然後再使用他獲取我們想要的結果.是不是有點感覺像資料庫連線池?那麼一般形式程式碼如下:
public String get(final String key) {
Jedis jedis = jedisPool.getResource();
String result = jedis.get(key);
jedis.close();
return result;
}
然而這樣寫方法多的話,每一個都要如此重複獲取,然後執行,然後關閉,返回結果,一套流程,就像模板一樣,那麼設計模式就可以考慮模板模式.
模板設計模式主要是將通用的邏輯都抽離出來,不通用的邏輯根據實現類的具體策略而執行不同的策略.因為JedisPool
比較類似資料庫連線池,因此我們可以參考Spring裡的JdbcTemplate
,裡面有如下程式碼:
public <T> T execute(ConnectionCallback<T> action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
//獲取連線
Connection con = DataSourceUtils.getConnection(getDataSource());
try {
Connection conToUse = con;
if (this.nativeJdbcExtractor != null) {
conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
}
else {
// Create close-suppressing Connection proxy, also preparing returned Statements.
conToUse = createConnectionProxy(con);
}
//執行策略
return action.doInConnection(conToUse);
}
catch (SQLException ex) {
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("ConnectionCallback", getSql(action), ex);
}
finally {
//關閉連線
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
分析:
程式碼分為三部分,獲取連線,執行策略,關閉釋放連線.除了策略,其他都是模板,而策略是一個函式式介面,如下:
public interface ConnectionCallback<T> {
T doInConnection(Connection con) throws SQLException, DataAccessException;
}
那麼具體策略就是實現該介面的實現類裡面的策略了.這樣就很好地做到模板和策略分離,還有一個好處就是函式式介面可以很好地配合java8語法,寫出相當優雅的程式碼.
2.實現
2.1 函式式介面實現
首先參照Spring,實現自己的函式式介面:
比上面多了一個泛型E代表傳入引數,這樣做的話,就會使得該介面更加具有通用性.
/**
* 模仿Spring ConnectionCallback寫的模板介面
* T為操作返回值 E為引數型別
* 配合java8使用,效果更佳
* @author Niu Li
* @date 2016/12/8
*/
public interface WorkCallback<T,E> {
/**
* 具體執行策略
* @param e 傳入引數
* @return 結果
*/
T doWorkCallback(E e);
}
2.2 實現單機版Jedis
實現思路,首先在JedisClientSingle
寫一個私有的excute方法,用於實現函式式介面,定義不同策略,程式碼具體如下:
/**
* 單機版jedis(配置建議都放在依賴注入配置中)
* @author Niu Li
* @date 2016/12/8
*/
public class JedisClientSingle{
/**
* 連線池,建議使用其他工具注入進來
*/
private JedisPool jedisPool;
public String get(final String key) {
return excute(new WorkCallback<String, Jedis>() {
public String doWorkCallback(Jedis jedis) {
return jedis.get(key);
}
});
}
public String set(final String key, final String value) {
return excute(new WorkCallback<String, Jedis>() {
public String doWorkCallback(Jedis jedis) {
return jedis.set(key,value);
}
});
}
/**
* 模板方法,很適合提取公共操作
* @param workCallback 處理函式
* @param <T> 返回型別
* @return 結果
*/
private <T> T excute(WorkCallback<T, Jedis> workCallback) {
Jedis jedis=null;
try {
jedis = jedisPool.getResource();
return workCallback.doWorkCallback(jedis);
} catch (Exception e) {
e.printStackTrace();
}finally {
if (null !=jedis){
jedis.close();
}
}
return null;
}
}
對於jedisPool
的注入的話,Spring中可以如下配置
<!-- 配置redis客戶端單機版 -->
<bean id="jedispoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.maxactive}"/>
<property name="maxIdle" value="${redis.maxidle}"/>
<property name="minIdle" value="${redis.minidle}"/>
<property name="maxWaitMillis" value="${redis.timeout}"/>
</bean>
<bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="destroy" depends-on="jedispoolConfig">
<constructor-arg name="poolConfig" ref="jedispoolConfig"/>
<constructor-arg name="host" value="${redis.ip}"/>
<constructor-arg name="port" value="${redis.port}"/>
</bean>
2.3實現叢集版
叢集版就簡單很多了,只能說Jedis封裝的太好了
/**
* jedis叢集
* @author Niu Li
* @date 2016/12/8
*/
public class JedisClientCluster {
/**
* 叢集控制,建議使用其他工具注入進來
*/
private JedisCluster jedisCluster;
/**
* 其他的直接使用jedisCluster的方法即可
*/
public String get(final String key) {
return jedisCluster.get(key);
}
}
對於jedisCluster
的注入,Spring配置如下:
<!-- 配置redis客戶端叢集版 -->
<!--<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
<constructor-arg>
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.1.101"/>
<constructor-arg name="port" value="1001"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.1.101"/>
<constructor-arg name="port" value="1002"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.1.101"/>
<constructor-arg name="port" value="1003"/>
</bean>
</set>
</constructor-arg>
</bean>
這種實現是不是很優雅?
參考程式碼:
https://github.com/nl101531/JavaWEB 下Util-Demo
參考連結:
本文從該部落格學習總結而得
https://muyinchen.github.io
相關文章
- Redis筆記2:Jedis連線池Redis筆記
- Jedis使用連線池操作redis叢集Redis
- Redis筆記3:Jedis連線自動釋放Redis筆記
- redis(二)redis概述與jedis的使用Redis
- redis 原始碼分析:Jedis 哨兵模式連線原理Redis原始碼模式
- redis學習(1)python連線redisRedisPython
- 解決使用jedis連線是報DENIED Redis is running in protected mode錯誤Redis
- Redis 佇列學習記錄Redis佇列
- 學習redis問題記錄Redis
- 小白的學習記錄——Redis的簡單使用Redis
- Vue 學習記錄二Vue
- Java學習筆記記錄(二)Java筆記
- gRPC學習記錄(六)--客戶端連線池RPC客戶端
- java操作redis。jedis使用apiJavaRedisAPI
- Java openrasp學習記錄(二)Java
- Redis學習筆記(二)——Redis資料型別Redis筆記資料型別
- Redis學習筆記(Jedis&資料型別&持久化&主從複製)Redis筆記資料型別持久化
- 【每日學習記錄】使用錄影裝置記錄每天的學習
- 學習連連看 連線線之謎+道具的使用
- [Redis 系列]redis 學習二Redis
- 【Redis 系列】redis 學習二Redis
- redis學習手記(二)持久化方式Redis持久化
- Web - Redis & JedisWebRedis
- Redis(15) jedisRedis
- jedis操作 redisRedis
- redis學習——目錄Redis
- Redis連線超時排查實錄Redis
- 使用telnet連線redisRedis
- 組合語言-學習記錄(二)組合語言
- substrate學習筆記13:連線parachain筆記AI
- Activiti 學習筆記七:連線(SequenceFlow)筆記
- MySQL學習筆記之多表連線MySql筆記
- Redis學習筆記(二)redis 底層資料結構Redis筆記資料結構
- Redis 使用記錄(一)Redis
- 深入學習Redis(二)Redis
- Jedis 連線 Redis報JedisConnectionException: java.net.ConnectException: Connection refusedRedisExceptionJava
- golang開發:類庫篇(二) Redis連線池的使用GolangRedis
- MYSQL學習筆記23: 多表查詢(自連線內連線+左右外連線)MySql筆記