Redis - Spring 整合 Redis(RedisTemplate)
阿新 • • 發佈:2018-12-21
Jedis是Redis官方推薦的面向Java的操作Redis的客戶端,而RedisTemplate是SpringDataRedis中對JedisApi的高度封裝。
SpringDataRedis相對於Jedis來說可以方便地更換Redis的Java客戶端,比Jedis多了自動管理連線池的特性,方便與其他Spring框架進行搭配使用如:SpringCache。關於哨兵模式的配置,我是參考網上的,只是把配置拿到了這裡,本人並沒有親測是否有效,程式碼是註釋掉的,需要配置哨兵模式的,可以參考一下。
Maven依賴
<!-- Redis客戶端 --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <!-- redis Spring 基於註解配置 --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.7.2.RELEASE</version> </dependency>
redis.properties
#ip地址 redis.hostName=172.20.1.205 #埠號 redis.port=6379 #如果有密碼 redis.password=123456 #客戶端超時時間單位是毫秒 預設是2000 redis.timeout=10000 #最大空閒數 redis.maxIdle=300 #連線池的最大資料庫連線數。設為0表示無限制,如果是jedis 2.4以後用redis.maxTotal #redis.maxActive=600 #控制一個pool可分配多少個jedis例項,用來替換上面的redis.maxActive,如果是jedis 2.4以後用該屬性 redis.maxTotal=1000 #最大建立連線等待時間。如果超過此時間將接到異常。設為-1表示無限制。 redis.maxWaitMillis=1000 #連線的最小空閒時間 預設1800000毫秒(30分鐘) redis.minEvictableIdleTimeMillis=300000 #每次釋放連線的最大數目,預設3 redis.numTestsPerEvictionRun=1024 #逐出掃描的時間間隔(毫秒) 如果為負數,則不執行逐出執行緒, 預設-1 redis.timeBetweenEvictionRunsMillis=30000 #是否在從池中取出連線前進行檢驗,如果檢驗失敗,則從池中去除連線並嘗試取出另一個 redis.testOnBorrow=true #在空閒時檢查有效性, 預設false redis.testWhileIdle=true #redis.sentinel.host1=172.20.1.230 #redis.sentinel.port1=26379 #redis.sentinel.host2=172.20.1.231 #redis.sentinel.port2=26379 #redis.sentinel.host3=172.20.1.232 #redis.sentinel.port3=26379
applicationContext-redis.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd"> <!-- 載入配置檔案 --> <context:property-placeholder location="classpath:properties/*.properties" /> <!-- redis連線池配置--> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" > <!--最大空閒數--> <property name="maxIdle" value="${redis.maxIdle}" /> <!--連線池的最大資料庫連線數 --> <property name="maxTotal" value="${redis.maxTotal}" /> <!--最大建立連線等待時間--> <property name="maxWaitMillis" value="${redis.maxWaitMillis}" /> <!--逐出連線的最小空閒時間 預設1800000毫秒(30分鐘)--> <property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}" /> <!--每次逐出檢查時 逐出的最大數目 如果為負數就是 : 1/abs(n), 預設3--> <property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}" /> <!--逐出掃描的時間間隔(毫秒) 如果為負數,則不執行逐出執行緒, 預設-1--> <property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}" /> <!--是否在從池中取出連線前進行檢驗,如果檢驗失敗,則從池中去除連線並嘗試取出另一個--> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> <!--在空閒時檢查有效性, 預設false --> <property name="testWhileIdle" value="${redis.testWhileIdle}" /> </bean > <!-- redis叢集配置 哨兵模式 --> <!-- <bean id="sentinelConfiguration" class="org.springframework.data.redis.connection.RedisSentinelConfiguration"> <property name="master"> <bean class="org.springframework.data.redis.connection.RedisNode"> 這個值要和Sentinel中指定的master的值一致,不然啟動時找不到Sentinel會報錯的 <property name="name" value="mymaster"></property> </bean> </property> 記住了,這裡是指定Sentinel的IP和埠,不是Master和Slave的 <property name="sentinels"> <set> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="${redis.sentinel.host1}"></constructor-arg> <constructor-arg name="port" value="${redis.sentinel.port1}"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="${redis.sentinel.host2}"></constructor-arg> <constructor-arg name="port" value="${redis.sentinel.port2}"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="${redis.sentinel.host3}"></constructor-arg> <constructor-arg name="port" value="${redis.sentinel.port3}"></constructor-arg> </bean> </set> </property> </bean> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <constructor-arg name="sentinelConfig" ref="sentinelConfiguration"></constructor-arg> <constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg> </bean> --> <!--redis連線工廠 --> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy"> <property name="poolConfig" ref="jedisPoolConfig"></property> <!--IP地址 --> <property name="hostName" value="${redis.hostName}"></property> <!--埠號 --> <property name="port" value="${redis.port}"></property> <!--如果Redis設定有密碼 --> <property name="password" value="${redis.password}" /> <!--客戶端超時時間單位是毫秒 --> <property name="timeout" value="${redis.timeout}"></property> </bean> <!--redis操作模版,使用該物件可以操作redis --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" > <property name="connectionFactory" ref="jedisConnectionFactory" /> <!--如果不配置Serializer,那麼儲存的時候預設使用String,如果用User型別儲存,那麼會提示錯誤User can't cast to String!! --> <property name="keySerializer" > <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> <property name="valueSerializer" > <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" /> </property> <property name="hashKeySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/> </property> <property name="hashValueSerializer"> <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/> </property> <!--開啟事務 --> <property name="enableTransactionSupport" value="true"></property> </bean > <!--自定義redis工具類,在需要快取的地方注入此類 --> <bean id="redisUtil" class="com.ryx.global.util.RedisUtil"> <property name="redisTemplate" ref="redisTemplate" /> </bean> </beans>
RedisUtil.java
package com.ryx.global.util;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* 基於spring和redis的redisTemplate工具類
* 針對所有的hash 都是以h開頭的方法
* 針對所有的Set 都是以s開頭的方法 不含通用方法
* 針對所有的List 都是以l開頭的方法
*/
public class RedisUtil {
private RedisTemplate<String, Object> redisTemplate;
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
//=============================common============================
/**
* 指定快取失效時間
* @param key 鍵
* @param time 時間(秒)
* @return
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根據key 獲取過期時間
* @param key 鍵 不能為null
* @return 時間(秒) 返回0代表為永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判斷key是否存在
* @param key 鍵
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 刪除快取
* @param key 可以傳一個值 或多個
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if ((key != null) && (key.length > 0)) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
//============================String=============================
/**
* 普通快取獲取
* @param key 鍵
* @return 值
*/
public Object get(String key) {
return (key == null) ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通快取放入
* @param key 鍵
* @param value 值
* @return true成功 false失敗
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通快取放入並設定時間
* @param key 鍵
* @param value 值
* @param time 時間(秒) time要大於0 如果time小於等於0 將設定無限期
* @return true成功 false 失敗
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue()
.set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 遞增
* @param key 鍵
* @param by 要增加幾(大於0)
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("遞增因子必須大於0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 遞減
* @param key 鍵
* @param by 要減少幾(小於0)
* @return
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("遞減因子必須大於0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
//================================Map=================================
/**
* HashGet
* @param key 鍵 不能為null
* @param item 項 不能為null
* @return 值
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 獲取hashKey對應的所有鍵值
* @param key 鍵
* @return 對應的多個鍵值
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
* @param key 鍵
* @param map 對應多個鍵值
* @return true 成功 false 失敗
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet 並設定時間
* @param key 鍵
* @param map 對應多個鍵值
* @param time 時間(秒)
* @return true成功 false失敗
*/
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一張hash表中放入資料,如果不存在將建立
* @param key 鍵
* @param item 項
* @param value 值
* @return true 成功 false失敗
*/
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一張hash表中放入資料,如果不存在將建立
* @param key 鍵
* @param item 項
* @param value 值
* @param time 時間(秒) 注意:如果已存在的hash表有時間,這裡將會替換原有的時間
* @return true 成功 false失敗
*/
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 刪除hash表中的值
* @param key 鍵 不能為null
* @param item 項 可以使多個 不能為null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判斷hash表中是否有該項的值
* @param key 鍵 不能為null
* @param item 項 不能為null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash遞增 如果不存在,就會建立一個 並把新增後的值返回
* @param key 鍵
* @param item 項
* @param by 要增加幾(大於0)
* @return
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash遞減
* @param key 鍵
* @param item 項
* @param by 要減少記(小於0)
* @return
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
//============================set=============================
/**
* 根據key獲取Set中的所有值
* @param key 鍵
* @return
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根據value從一個set中查詢,是否存在
* @param key 鍵
* @param value 值
* @return true 存在 false不存在
*/
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 將資料放入set快取
* @param key 鍵
* @param values 值 可以是多個
* @return 成功個數
*/
public long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 將set資料放入快取
* @param key 鍵
* @param time 時間(秒)
* @param values 值 可以是多個
* @return 成功個數
*/
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0) {
expire(key, time);
}
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 獲取set快取的長度
* @param key 鍵
* @return
*/
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 移除值為value的
* @param key 鍵
* @param values 值 可以是多個
* @return 移除的個數
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//===============================list=================================
/**
* 獲取list快取的內容
* @param key 鍵
* @param start 開始
* @param end 結束 0 到 -1代表所有值
* @return
*/
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 獲取list快取的長度
* @param key 鍵
* @return
*/
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 通過索引 獲取list中的值
* @param key 鍵
* @param index 索引 index>=0時, 0 表頭,1 第二個元素,依次類推;index<0時,-1,表尾,-2倒數第二個元素,依次類推
* @return
*/
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 將list放入快取
* @param key 鍵
* @param value 值
* @param time 時間(秒)
* @return
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 將list放入快取
* @param key 鍵
* @param value 值
* @param time 時間(秒)
* @return
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 將list放入快取
* @param key 鍵
* @param value 值
* @param time 時間(秒)
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 將list放入快取
* @param key 鍵
* @param value 值
* @param time 時間(秒)
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根據索引修改list中的某條資料
* @param key 鍵
* @param index 索引
* @param value 值
* @return
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 移除N個值為value
* @param key 鍵
* @param count 移除多少個
* @param value 值
* @return 移除的個數
*/
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}
TestRedis.java
package com.ryx.test;
import com.ryx.global.util.RedisUtil;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TestRedis {
public static void main(String[] args) throws Exception {
@SuppressWarnings("resource")
ApplicationContext context = new ClassPathXmlApplicationContext(
"classpath:spring/applicationContext-redis.xml");
RedisUtil redisUtil = (RedisUtil) context.getBean("redisUtil");
//=====================testString======================
//redisUtil.set("name", "王賽超");
//redisUtil.set("age", 24);
//redisUtil.set("address", "河北邯鄲");
//System.out.println(redisUtil.set("address", "河北邯鄲", 50));
//System.out.println(redisUtil.get("age"));
//redisUtil.set("age", 1000);
//Object object = redisUtil.get("user2");
//System.out.println(object);
//redisUtil.del("address");
//redisUtil.set("class", 15);
//long incr = redisUtil.incr("a", 1);
//System.out.println(incr);
//Thread.sleep(5000);
/*Map<String,Object> map=new HashMap<>();
map.put("name", "王賽超");
map.put("age", 24);
map.put("address", "河北邯鄲666");
redisUtil.hmset("15532002725", map,1000);*/
//redisUtil.del("15532002725");
//redisUtil.hset("15532002725","address","河北邯鄲",1000);
//redisUtil.hdel("15532002725", "name");
//System.out.println(redisUtil.sSetAndTime("15532002727",1000,"haha"));
//System.out.println(redisUtil.sGet("15532002727"));
//System.out.println(redisUtil.sHasKey("15532002727","name"));
System.out.println(redisUtil.lRemove("15532002728", 1, 2));
System.out.println(redisUtil.lGet("15532002728", 0, -1));
System.out.println(redisUtil.lGetListSize("15532002728"));
System.out.println(redisUtil.lGetIndex("15532002728", 1));
//System.out.println(redisUtil.getExpire("15532002725"));
//System.out.println(redisUtil.hget("15532002725","name"));
//System.out.println(redisUtil.hmget("15532002725"));
}
}
class User {
private String name;
private Integer age;
private String address;
private Double classz;
private Float classz2;
public User() {
super();
}
public User(String name, Integer age, String address, Double classz,
Float classz2) {
super();
this.name = name;
this.age = age;
this.address = address;
this.classz = classz;
this.classz2 = classz2;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Double getClassz() {
return classz;
}
public void setClassz(Double classz) {
this.classz = classz;
}
public Float getClassz2() {
return classz2;
}
public void setClassz2(Float classz2) {
this.classz2 = classz2;
}
}
轉自:https://blog.csdn.net/qq_34021712/article/details/75949706