【Redis】深入淺出Redis(三)——在專案中使用Jedis對Redis操作
一、前言
在前幾篇部落格中小編向大家介紹了搭建單機版和叢集版的redis。雖然叢集搭建起來了,但是如何在專案中使用呢?在這篇部落格中,小編向大家介紹Jedis,用Jedis來對Redis進行增加、刪除、設定有效時間等操作。
二、什麼是Jedis?
使用Jedis連線redis伺服器,Java客戶端在github上start最高的是Jedis和Redisson。Jedis提供了完整Redis命令,而Redisson有更多分散式的容器實現。
Jedis類是整個客戶端的入口,通過Jedis可以建立與Redis Server的連線併發送命令。Jedis繼承自BinaryJedis,同時Jedis和BinaryJedis都實現了很多介面,通過一張類圖來描述:
每一個介面都代表了一類Redis命令,例如JedisCommands中包含了SET GET等命令,MultiKeyCommands中包含了針對多個Key的MSET MGET等命令。一部分命令有兩個版本的介面,如JedisCommands和BinaryJedisCommands。JedisCommands是字串引數版本命令,會在Jedis內部將引數轉換成UTF-8編碼的位元組陣列。BinaryJedisCommands提供的是位元組引數版本,允許使用者自己決定編碼等細節。ClusterCommands和SentinelCommands與叢集、高可用等相關的命令只有一個版本。
三、具體實現
3.1 環境搭建
Redis
java maven專案
3.2 引入Jedis的jar包
向maven專案的pom.xml檔案中插入Jedis的座標:
<!-- Redis客戶端 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.2</version>
</dependency>
3.2 建立redis客戶端實現類
建立的這個類就是為了抽象redis的操作,我們都知道的redis有很多操作,這裡就封裝了redis的新增雜湊值、獲取雜湊值、增加1、減少1、設定有效時間、檢視有效時間、刪除等操作。並通過JedisClientSingle和JedisClientCluster,單機和叢集版分別實現了操作,不同的設定,使用不同的實現,系統很靈活。
JedisClient:
package com.taotao.rest.component;
public interface JedisClient {
public String set(String key,String value);
public String get(String key);
//新增雜湊值
public Long hset(String key,String item,String value);
//獲取雜湊
public String hget(String key,String item);
//增加1
public Long incr(String key);
//減少1
public Long decr(String key);
//設定有效時間
public Long expire(String key,int second);
//檢視當前有效時間
public Long ttl(String key);
//刪除
public Long hdel(String key,String item);
}
叢集版JedisClientCluster:
package com.taotao.rest.component.impl;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.JedisCluster;
import com.taotao.rest.component.JedisClient;
/**
* 叢集版
* @author Ares
*
*/
public class JedisClientCluster implements JedisClient {
@Autowired
private JedisCluster jedisCluster;
@Override
public String set(String key, String value) {
return jedisCluster.set(key, value);
}
@Override
public String get(String key) {
return jedisCluster.get(key);
}
@Override
public Long hset(String key, String item, String value) {
return jedisCluster.hset(key, item, value);
}
@Override
public String hget(String key, String item) {
return jedisCluster.hget(key, item);
}
@Override
public Long incr(String key) {
return jedisCluster.incr(key);
}
@Override
public Long decr(String key) {
return jedisCluster.decr(key);
}
@Override
public Long expire(String key, int second) {
return jedisCluster.expire(key, second);
}
@Override
public Long ttl(String key) {
return jedisCluster.ttl(key);
}
@Override
public Long hdel(String key, String item) {
return jedisCluster.hdel(key, item);
}
}
單機版JedisClientSingle:
package com.taotao.rest.component.impl;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import com.taotao.rest.component.JedisClient;
/**
* 單機版
*
* @author Ares
*
*/
public class JedisClientSingle implements JedisClient {
@Autowired
private JedisPool jedisPool;
/**
* 設定值K-V
*/
@Override
public String set(String key, String value) {
//建立連線
Jedis jedis = jedisPool.getResource();
//設定陣列
String result = jedis.set(key, value);
//關閉連線
jedis.close();
return result;
}
/**
* 獲取陣列
*/
@Override
public String get(String key) {
//建立連線
Jedis jedis = jedisPool.getResource();
//設定陣列
String result = jedis.get(key);
//關閉連線
jedis.close();
return result;
}
@Override
public Long hset(String key, String item, String value) {
//建立連線
Jedis jedis = jedisPool.getResource();
//設定雜湊
Long result = jedis.hset(key, item, value);
//關閉連線
jedis.close();
return result;
}
@Override
public String hget(String key, String item) {
//建立連線
Jedis jedis = jedisPool.getResource();
//讀取雜湊
String result = jedis.hget(key, item);
//關閉連線
jedis.close();
return result;
}
@Override
public Long incr(String key) {
//建立連線
Jedis jedis = jedisPool.getResource();
//+1
Long result = jedis.incr(key);
//關閉連線
jedis.close();
return result;
}
@Override
public Long decr(String key) {
//建立連線
Jedis jedis = jedisPool.getResource();
//-1
Long result = jedis.decr(key);
//關閉連線
jedis.close();
return result;
}
@Override
public Long expire(String key, int second) {
//建立連線
Jedis jedis = jedisPool.getResource();
//設定有效時間
Long result = jedis.expire(key,second);
//關閉連線
jedis.close();
return result;
}
@Override
public Long ttl(String key) {
//建立連線
Jedis jedis = jedisPool.getResource();
//檢視有效時間
Long result = jedis.ttl(key);
//關閉連線
jedis.close();
return result;
}
@Override
public Long hdel(String key, String item) {
//建立連線
Jedis jedis = jedisPool.getResource();
//檢視有效時間
Long result = jedis.hdel(key, item);
//關閉連線
jedis.close();
return result;
}
}
3.2 託付給Spring管理
這裡我們把Redis客戶端託付給Spring管理,配置Redis的主機地址以及埠。
然後配置redis客戶端的實現類,這裡小編列出了單機版和叢集版兩種。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!-- 包掃描器,掃描帶@Service註解的類 -->
<context:component-scan base-package="com.taotao.rest.service"></context:component-scan>
<!-- 配置redis客戶端單機版 -->
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg name="host" value="192.168.137.12"></constructor-arg>
<constructor-arg name="port" value="6379"></constructor-arg>
</bean>
<!-- 配置redis客戶端實現類 -->
<bean id="jedisClientSingle" class="com.taotao.rest.component.impl.JedisClientSingle"/>
<!-- 配置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.137.12"/>
<constructor-arg name="port" value="7001"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.137.12"/>
<constructor-arg name="port" value="7002"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.137.12"/>
<constructor-arg name="port" value="7003"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.137.12"/>
<constructor-arg name="port" value="7004"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.137.12"/>
<constructor-arg name="port" value="7005"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.137.12"/>
<constructor-arg name="port" value="7006"/>
</bean>
</set>
</constructor-arg>
</bean>
<bean id="jedisClientCluster" class="com.taotao.rest.component.impl.JedisClientCluster"/> -->
</beans>
3.5 業務邏輯中新增快取
注意:新增快取時不要影響正常的業務邏輯
@Override
public List<TbContent> getContentList(Long cid) {
//新增快取
//查詢資料庫之前先查詢快取,如果有直接返回
try {
//從redis中取快取資料
String json = jedisClient.hget(REDIS_CONTENT_KEY, cid+"");
if (!StringUtils.isBlank(json)) {
//把json轉換成List
List<TbContent> list = JsonUtils.jsonToList(json, TbContent.class);
return list;
}
} catch (Exception e) {
e.printStackTrace();
}
// 根據cid查詢內容列表
TbContentExample example = new TbContentExample();
Criteria criteria = example.createCriteria();
criteria.andCategoryIdEqualTo(cid);
//執行查詢
List<TbContent> list = contentMapper.selectByExampleWithBLOBs(example);
//返回結果之前,向快取中新增資料
try {
//為了規範key可以使用hash
//定義一個儲存內容的key,hash中每個項就是cid
//value是list,需要把list轉換成json資料。
jedisClient.hset(REDIS_CONTENT_KEY, cid+"", JsonUtils.objectToJson(list));
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
四、小結
通過使用Jedis,可以對redis進行操作。這樣快取我們就可以很好的使用了,另外就是對快取使用的時候不能影響業務邏輯。還要設定超時時間,如果連結超時也要進行資料庫查詢了。
下一篇部落格將向大家介紹redis的快取同步問題。