您好,登錄后才能下訂單哦!
這篇文章主要介紹“redis使用實例分析”,在日常操作中,相信很多人在redis使用實例分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”redis使用實例分析”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
首先我們為要先了解,我們在原先使用mysql的時候,用jdbc連接數據庫。同理這里我們連接redis,就要使用jedis。
新建java項目,導包
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.73</version> </dependency>
打開redis服務
新建一個測試類,寫一個方法
public class Ping { public static void main(String[] args) { Jedis jedis = new Jedis("127.0.0.1",6379); System.out.println("連接成功"); //查看服務是否運行 System.out.println("服務正在運行: "+jedis.ping()); } }
證明連同了
這里寫一些簡單的jedis對各種類型的操作
public class TestPassword { public static void main(String[] args) { Jedis jedis = new Jedis("127.0.0.1", 6379); //驗證密碼,如果沒有設置密碼這段代碼省略 // jedis.auth("password"); jedis.connect(); //連接 jedis.disconnect(); //斷開連接 jedis.flushAll(); //清空所有的key } }
public class TestKey { public static void main(String[] args) { Jedis jedis = new Jedis("127.0.0.1", 6379); System.out.println("清空數據:"+jedis.flushDB()); System.out.println("判斷某個鍵是否在:"+jedis.exists("username")); System.out.println("新增<'username','kuangshen'>的鍵值對:"+jedis.set("username", "kuangshen")); System.out.println("新增<'password','password'>的鍵值 對:"+jedis.set("password", "password")); System.out.print("系統中所有的鍵如下:"); Set<String> keys = jedis.keys("*"); System.out.println(keys); System.out.println("刪除鍵password:"+jedis.del("password")); System.out.println("判斷鍵password是否存在:"+jedis.exists("password")); System.out.println("查看鍵username所存儲的值的類 型:"+jedis.type("username")); System.out.println("隨機返回key空間的一個:"+jedis.randomKey()); System.out.println("重命名key:"+jedis.rename("username","name")); System.out.println("取出改后的name:"+jedis.get("name")); System.out.println("按索引查詢:"+jedis.select(0)); System.out.println("刪除當前選擇數據庫中的所key:"+jedis.flushDB()); System.out.println("返回當前數據庫中key的數目:"+jedis.dbSize()); System.out.println("刪除所有數據庫中的所有key:"+jedis.flushAll()); } }
public class TestString { public static void main(String[] args) { Jedis jedis = new Jedis("127.0.0.1", 6379); jedis.flushDB(); System.out.println("===========增加數據==========="); System.out.println(jedis.set("key1","value1")); System.out.println(jedis.set("key2","value2")); System.out.println(jedis.set("key3", "value3")); System.out.println("刪除鍵key2:"+jedis.del("key2")); System.out.println("獲取鍵key2:"+jedis.get("key2")); System.out.println("修改key1:"+jedis.set("key1", "value1Changed")); System.out.println("獲取key1的值:"+jedis.get("key1")); System.out.println("在key3后面加入值:"+jedis.append("key3", "End")); System.out.println("key3的值:"+jedis.get("key3")); System.out.println("增加多個鍵值 對:"+jedis.mset("key01","value01","key02","value02","key03","value03")); System.out.println("獲取多個鍵值 對:"+jedis.mget("key01","key02","key03")); System.out.println("獲取多個鍵值 對:"+jedis.mget("key01","key02","key03","key04")); System.out.println("刪除多個鍵值對:"+jedis.del("key01","key02")); System.out.println("獲取多個鍵值 對:"+jedis.mget("key01","key02","key03")); jedis.flushDB(); System.out.println("===========新增鍵值對防止覆蓋原先值=============="); System.out.println(jedis.setnx("key1", "value1")); System.out.println(jedis.setnx("key2", "value2")); System.out.println(jedis.setnx("key2", "value2-new")); System.out.println(jedis.get("key1")); System.out.println(jedis.get("key2")); System.out.println("===========新增鍵值對并設置有效時間============="); System.out.println(jedis.setex("key3", 2, "value3")); System.out.println(jedis.get("key3")); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(jedis.get("key3")); System.out.println("===========獲取原值,更新為新值=========="); System.out.println(jedis.getSet("key2", "key2GetSet")); System.out.println(jedis.get("key2")); System.out.println("獲得key2的值的字串:"+jedis.getrange("key2", 2, 4)); } }
public class TestMulti { public static void main(String[] args) { //創建客戶端連接服務端,redis服務端需要被開啟 Jedis jedis = new Jedis("127.0.0.1", 6379); jedis.flushDB(); JSONObject jsonObject = new JSONObject(); jsonObject.put("hello", "world"); jsonObject.put("name", "java"); //開啟事務 Transaction multi = jedis.multi(); String result = jsonObject.toJSONString(); try{ //向redis存入一條數據 multi.set("json", result); //再存入一條數據 multi.set("json2", result); //這里引發了異常,用0作為被除數 int i = 100/0; //如果沒有引發異常,執行進入隊列的命令 multi.exec(); }catch(Exception e){ e.printStackTrace(); //如果出現異常,回滾 multi.discard(); }finally{ System.out.println(jedis.get("json")); System.out.println(jedis.get("json2")); //最終關閉客戶端 jedis.close(); } } }
在SpringBoot中一般使用RedisTemplate提供的方法來操作Redis。
源碼分析
@Bean @ConditionalOnMissingBean(name = {"redisTemplate"}) // 我們可以自己定一個redisTemplate來替換這個默認的! public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { // 默認的RedisTemplate沒有過多的設置,redis對象都是需要序列化的 // 兩個泛型都是Object,Object類型的,我們后續使用需要強制轉換成<String,Object> RedisTemplate<Object, Object> template = new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; } @Bean @ConditionalOnMissingBean public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; }
導入依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
yml文件配置
spring.redis.host=127.0.0.1 spring.redis.port=6379
測試
@SpringBootTest class Redis02SpringbootApplicationTests { @Autowired private RedisTemplate redisTemplate; @Test void contextLoads() { redisTemplate.opsForValue().set("mykey", "我是大帥哥"); System.out.println(redisTemplate.opsForValue().get("mykey")); } }
通過開頭的源碼可以看出,SpringBoot自動幫我們在容器中生成了一個RedisTemplate和一個StringRedisTemplate。但是,這個RedisTemplate的泛型是<Object,Object>,寫代碼不方便,需要寫好多類型轉換的代碼;我們需要一個泛型為<String,Object>形式RedisTemplate。并且,這個RedisTemplate沒有設置數據存在Redis時,key及value的序列化方式。看到這個@ConditionalOnMissingBean注解后,就知道如果Spring容器中有了RedisTemplate對象了,這個自動配置的RedisTemplate不會實例化。因此我們可以直接自己寫個配置類,配置RedisTemplate。
自定義RedisTemplate
@Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<String, Object> template = new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); // 序列化配置 Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(); objectJackson2JsonRedisSerializer.setObjectMapper(om); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); template.setKeySerializer(stringRedisSerializer); template.setHashKeySerializer(stringRedisSerializer); template.setValueSerializer(objectJackson2JsonRedisSerializer); template.setHashValueSerializer(objectJackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } }
寫一個Redis工具類(直接用RedisTemplate操作Redis,需要很多行代碼,因此直接封裝好一個RedisUtils,這樣寫代碼更方便點。這個RedisUtils交給Spring容器實例化,使用時直接注解注入。)
這里是別人寫的工具類,很全!!!
import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ZSetOperations.TypedTuple; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.TimeUnit; /** * Redis工具類*/ public class RedisUtil { private StringRedisTemplate redisTemplate; public void setRedisTemplate(StringRedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; } public StringRedisTemplate getRedisTemplate() { return this.redisTemplate; } /** -------------------key相關操作--------------------- */ /** * 刪除key * * @param key */ public void delete(String key) { redisTemplate.delete(key); } /** * 批量刪除key * * @param keys */ public void delete(Collection<String> keys) { redisTemplate.delete(keys); } /** * 序列化key * * @param key * @return */ public byte[] dump(String key) { return redisTemplate.dump(key); } /** * 是否存在key * * @param key * @return */ public Boolean hasKey(String key) { return redisTemplate.hasKey(key); } /** * 設置過期時間 * * @param key * @param timeout * @param unit * @return */ public Boolean expire(String key, long timeout, TimeUnit unit) { return redisTemplate.expire(key, timeout, unit); } /** * 設置過期時間 * * @param key * @param date * @return */ public Boolean expireAt(String key, Date date) { return redisTemplate.expireAt(key, date); } /** * 查找匹配的key * * @param pattern * @return */ public Set<String> keys(String pattern) { return redisTemplate.keys(pattern); } /** * 將當前數據庫的 key 移動到給定的數據庫 db 當中 * * @param key * @param dbIndex * @return */ public Boolean move(String key, int dbIndex) { return redisTemplate.move(key, dbIndex); } /** * 移除 key 的過期時間,key 將持久保持 * * @param key * @return */ public Boolean persist(String key) { return redisTemplate.persist(key); } /** * 返回 key 的剩余的過期時間 * * @param key * @param unit * @return */ public Long getExpire(String key, TimeUnit unit) { return redisTemplate.getExpire(key, unit); } /** * 返回 key 的剩余的過期時間 * * @param key * @return */ public Long getExpire(String key) { return redisTemplate.getExpire(key); } /** * 從當前數據庫中隨機返回一個 key * * @return */ public String randomKey() { return redisTemplate.randomKey(); } /** * 修改 key 的名稱 * * @param oldKey * @param newKey */ public void rename(String oldKey, String newKey) { redisTemplate.rename(oldKey, newKey); } /** * 僅當 newkey 不存在時,將 oldKey 改名為 newkey * * @param oldKey * @param newKey * @return */ public Boolean renameIfAbsent(String oldKey, String newKey) { return redisTemplate.renameIfAbsent(oldKey, newKey); } /** * 返回 key 所儲存的值的類型 * * @param key * @return */ public DataType type(String key) { return redisTemplate.type(key); } /** -------------------string相關操作--------------------- */ /** * 設置指定 key 的值 * @param key * @param value */ public void set(String key, String value) { redisTemplate.opsForValue().set(key, value); } /** * 獲取指定 key 的值 * @param key * @return */ public String get(String key) { return redisTemplate.opsForValue().get(key); } /** * 返回 key 中字符串值的子字符 * @param key * @param start * @param end * @return */ public String getRange(String key, long start, long end) { return redisTemplate.opsForValue().get(key, start, end); } /** * 將給定 key 的值設為 value ,并返回 key 的舊值(old value) * * @param key * @param value * @return */ public String getAndSet(String key, String value) { return redisTemplate.opsForValue().getAndSet(key, value); } /** * 對 key 所儲存的字符串值,獲取指定偏移量上的位(bit) * * @param key * @param offset * @return */ public Boolean getBit(String key, long offset) { return redisTemplate.opsForValue().getBit(key, offset); } /** * 批量獲取 * * @param keys * @return */ public List<String> multiGet(Collection<String> keys) { return redisTemplate.opsForValue().multiGet(keys); } /** * 設置ASCII碼, 字符串'a'的ASCII碼是97, 轉為二進制是'01100001', 此方法是將二進制第offset位值變為value * * @param key 位置 * @param value * 值,true為1, false為0 * @return */ public boolean setBit(String key, long offset, boolean value) { return redisTemplate.opsForValue().setBit(key, offset, value); } /** * 將值 value 關聯到 key ,并將 key 的過期時間設為 timeout * * @param key * @param value * @param timeout * 過期時間 * @param unit * 時間單位, 天:TimeUnit.DAYS 小時:TimeUnit.HOURS 分鐘:TimeUnit.MINUTES * 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS */ public void setEx(String key, String value, long timeout, TimeUnit unit) { redisTemplate.opsForValue().set(key, value, timeout, unit); } /** * 只有在 key 不存在時設置 key 的值 * * @param key * @param value * @return 之前已經存在返回false,不存在返回true */ public boolean setIfAbsent(String key, String value) { return redisTemplate.opsForValue().setIfAbsent(key, value); } /** * 用 value 參數覆寫給定 key 所儲存的字符串值,從偏移量 offset 開始 * * @param key * @param value * @param offset * 從指定位置開始覆寫 */ public void setRange(String key, String value, long offset) { redisTemplate.opsForValue().set(key, value, offset); } /** * 獲取字符串的長度 * * @param key * @return */ public Long size(String key) { return redisTemplate.opsForValue().size(key); } /** * 批量添加 * * @param maps */ public void multiSet(Map<String, String> maps) { redisTemplate.opsForValue().multiSet(maps); } /** * 同時設置一個或多個 key-value 對,當且僅當所有給定 key 都不存在 * * @param maps * @return 之前已經存在返回false,不存在返回true */ public boolean multiSetIfAbsent(Map<String, String> maps) { return redisTemplate.opsForValue().multiSetIfAbsent(maps); } /** * 增加(自增長), 負數則為自減 * * @param key * @return */ public Long incrBy(String key, long increment) { return redisTemplate.opsForValue().increment(key, increment); } /** * * @param key * @return */ public Double incrByFloat(String key, double increment) { return redisTemplate.opsForValue().increment(key, increment); } /** * 追加到末尾 * * @param key * @param value * @return */ public Integer append(String key, String value) { return redisTemplate.opsForValue().append(key, value); } /** -------------------hash相關操作------------------------- */ /** * 獲取存儲在哈希表中指定字段的值 * * @param key * @param field * @return */ public Object hGet(String key, String field) { return redisTemplate.opsForHash().get(key, field); } /** * 獲取所有給定字段的值 * * @param key * @return */ public Map<Object, Object> hGetAll(String key) { return redisTemplate.opsForHash().entries(key); } /** * 獲取所有給定字段的值 * * @param key * @param fields * @return */ public List<Object> hMultiGet(String key, Collection<Object> fields) { return redisTemplate.opsForHash().multiGet(key, fields); } public void hPut(String key, String hashKey, String value) { redisTemplate.opsForHash().put(key, hashKey, value); } public void hPutAll(String key, Map<String, String> maps) { redisTemplate.opsForHash().putAll(key, maps); } /** * 僅當hashKey不存在時才設置 * * @param key * @param hashKey * @param value * @return */ public Boolean hPutIfAbsent(String key, String hashKey, String value) { return redisTemplate.opsForHash().putIfAbsent(key, hashKey, value); } /** * 刪除一個或多個哈希表字段 * * @param key * @param fields * @return */ public Long hDelete(String key, Object... fields) { return redisTemplate.opsForHash().delete(key, fields); } /** * 查看哈希表 key 中,指定的字段是否存在 * * @param key * @param field * @return */ public boolean hExists(String key, String field) { return redisTemplate.opsForHash().hasKey(key, field); } /** * 為哈希表 key 中的指定字段的整數值加上增量 increment * * @param key * @param field * @param increment * @return */ public Long hIncrBy(String key, Object field, long increment) { return redisTemplate.opsForHash().increment(key, field, increment); } /** * 為哈希表 key 中的指定字段的整數值加上增量 increment * * @param key * @param field * @param delta * @return */ public Double hIncrByFloat(String key, Object field, double delta) { return redisTemplate.opsForHash().increment(key, field, delta); } /** * 獲取所有哈希表中的字段 * * @param key * @return */ public Set<Object> hKeys(String key) { return redisTemplate.opsForHash().keys(key); } /** * 獲取哈希表中字段的數量 * * @param key * @return */ public Long hSize(String key) { return redisTemplate.opsForHash().size(key); } /** * 獲取哈希表中所有值 * * @param key * @return */ public List<Object> hValues(String key) { return redisTemplate.opsForHash().values(key); } /** * 迭代哈希表中的鍵值對 * * @param key * @param options * @return */ public Cursor<Entry<Object, Object>> hScan(String key, ScanOptions options) { return redisTemplate.opsForHash().scan(key, options); } /** ------------------------list相關操作---------------------------- */ /** * 通過索引獲取列表中的元素 * * @param key * @param index * @return */ public String lIndex(String key, long index) { return redisTemplate.opsForList().index(key, index); } /** * 獲取列表指定范圍內的元素 * * @param key * @param start * 開始位置, 0是開始位置 * @param end * 結束位置, -1返回所有 * @return */ public List<String> lRange(String key, long start, long end) { return redisTemplate.opsForList().range(key, start, end); } /** * 存儲在list頭部 * * @param key * @param value * @return */ public Long lLeftPush(String key, String value) { return redisTemplate.opsForList().leftPush(key, value); } /** * * @param key * @param value * @return */ public Long lLeftPushAll(String key, String... value) { return redisTemplate.opsForList().leftPushAll(key, value); } /** * * @param key * @param value * @return */ public Long lLeftPushAll(String key, Collection<String> value) { return redisTemplate.opsForList().leftPushAll(key, value); } /** * 當list存在的時候才加入 * * @param key * @param value * @return */ public Long lLeftPushIfPresent(String key, String value) { return redisTemplate.opsForList().leftPushIfPresent(key, value); } /** * 如果pivot存在,再pivot前面添加 * * @param key * @param pivot * @param value * @return */ public Long lLeftPush(String key, String pivot, String value) { return redisTemplate.opsForList().leftPush(key, pivot, value); } /** * * @param key * @param value * @return */ public Long lRightPush(String key, String value) { return redisTemplate.opsForList().rightPush(key, value); } /** * * @param key * @param value * @return */ public Long lRightPushAll(String key, String... value) { return redisTemplate.opsForList().rightPushAll(key, value); } /** * * @param key * @param value * @return */ public Long lRightPushAll(String key, Collection<String> value) { return redisTemplate.opsForList().rightPushAll(key, value); } /** * 為已存在的列表添加值 * * @param key * @param value * @return */ public Long lRightPushIfPresent(String key, String value) { return redisTemplate.opsForList().rightPushIfPresent(key, value); } /** * 在pivot元素的右邊添加值 * * @param key * @param pivot * @param value * @return */ public Long lRightPush(String key, String pivot, String value) { return redisTemplate.opsForList().rightPush(key, pivot, value); } /** * 通過索引設置列表元素的值 * * @param key * @param index * 位置 * @param value */ public void lSet(String key, long index, String value) { redisTemplate.opsForList().set(key, index, value); } /** * 移出并獲取列表的第一個元素 * * @param key * @return 刪除的元素 */ public String lLeftPop(String key) { return redisTemplate.opsForList().leftPop(key); } /** * 移出并獲取列表的第一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止 * * @param key * @param timeout * 等待時間 * @param unit * 時間單位 * @return */ public String lBLeftPop(String key, long timeout, TimeUnit unit) { return redisTemplate.opsForList().leftPop(key, timeout, unit); } /** * 移除并獲取列表最后一個元素 * * @param key * @return 刪除的元素 */ public String lRightPop(String key) { return redisTemplate.opsForList().rightPop(key); } /** * 移出并獲取列表的最后一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止 * * @param key * @param timeout * 等待時間 * @param unit * 時間單位 * @return */ public String lBRightPop(String key, long timeout, TimeUnit unit) { return redisTemplate.opsForList().rightPop(key, timeout, unit); } /** * 移除列表的最后一個元素,并將該元素添加到另一個列表并返回 * * @param sourceKey * @param destinationKey * @return */ public String lRightPopAndLeftPush(String sourceKey, String destinationKey) { return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, destinationKey); } /** * 從列表中彈出一個值,將彈出的元素插入到另外一個列表中并返回它; 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止 * * @param sourceKey * @param destinationKey * @param timeout * @param unit * @return */ public String lBRightPopAndLeftPush(String sourceKey, String destinationKey, long timeout, TimeUnit unit) { return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, destinationKey, timeout, unit); } /** * 刪除集合中值等于value得元素 * * @param key * @param index * index=0, 刪除所有值等于value的元素; index>0, 從頭部開始刪除第一個值等于value的元素; * index<0, 從尾部開始刪除第一個值等于value的元素; * @param value * @return */ public Long lRemove(String key, long index, String value) { return redisTemplate.opsForList().remove(key, index, value); } /** * 裁剪list * * @param key * @param start * @param end */ public void lTrim(String key, long start, long end) { redisTemplate.opsForList().trim(key, start, end); } /** * 獲取列表長度 * * @param key * @return */ public Long lLen(String key) { return redisTemplate.opsForList().size(key); } /** --------------------set相關操作-------------------------- */ /** * set添加元素 * * @param key * @param values * @return */ public Long sAdd(String key, String... values) { return redisTemplate.opsForSet().add(key, values); } /** * set移除元素 * * @param key * @param values * @return */ public Long sRemove(String key, Object... values) { return redisTemplate.opsForSet().remove(key, values); } /** * 移除并返回集合的一個隨機元素 * * @param key * @return */ public String sPop(String key) { return redisTemplate.opsForSet().pop(key); } /** * 將元素value從一個集合移到另一個集合 * * @param key * @param value * @param destKey * @return */ public Boolean sMove(String key, String value, String destKey) { return redisTemplate.opsForSet().move(key, value, destKey); } /** * 獲取集合的大小 * * @param key * @return */ public Long sSize(String key) { return redisTemplate.opsForSet().size(key); } /** * 判斷集合是否包含value * * @param key * @param value * @return */ public Boolean sIsMember(String key, Object value) { return redisTemplate.opsForSet().isMember(key, value); } /** * 獲取兩個集合的交集 * * @param key * @param otherKey * @return */ public Set<String> sIntersect(String key, String otherKey) { return redisTemplate.opsForSet().intersect(key, otherKey); } /** * 獲取key集合與多個集合的交集 * * @param key * @param otherKeys * @return */ public Set<String> sIntersect(String key, Collection<String> otherKeys) { return redisTemplate.opsForSet().intersect(key, otherKeys); } /** * key集合與otherKey集合的交集存儲到destKey集合中 * * @param key * @param otherKey * @param destKey * @return */ public Long sIntersectAndStore(String key, String otherKey, String destKey) { return redisTemplate.opsForSet().intersectAndStore(key, otherKey, destKey); } /** * key集合與多個集合的交集存儲到destKey集合中 * * @param key * @param otherKeys * @param destKey * @return */ public Long sIntersectAndStore(String key, Collection<String> otherKeys, String destKey) { return redisTemplate.opsForSet().intersectAndStore(key, otherKeys, destKey); } /** * 獲取兩個集合的并集 * * @param key * @param otherKeys * @return */ public Set<String> sUnion(String key, String otherKeys) { return redisTemplate.opsForSet().union(key, otherKeys); } /** * 獲取key集合與多個集合的并集 * * @param key * @param otherKeys * @return */ public Set<String> sUnion(String key, Collection<String> otherKeys) { return redisTemplate.opsForSet().union(key, otherKeys); } /** * key集合與otherKey集合的并集存儲到destKey中 * * @param key * @param otherKey * @param destKey * @return */ public Long sUnionAndStore(String key, String otherKey, String destKey) { return redisTemplate.opsForSet().unionAndStore(key, otherKey, destKey); } /** * key集合與多個集合的并集存儲到destKey中 * * @param key * @param otherKeys * @param destKey * @return */ public Long sUnionAndStore(String key, Collection<String> otherKeys, String destKey) { return redisTemplate.opsForSet().unionAndStore(key, otherKeys, destKey); } /** * 獲取兩個集合的差集 * * @param key * @param otherKey * @return */ public Set<String> sDifference(String key, String otherKey) { return redisTemplate.opsForSet().difference(key, otherKey); } /** * 獲取key集合與多個集合的差集 * * @param key * @param otherKeys * @return */ public Set<String> sDifference(String key, Collection<String> otherKeys) { return redisTemplate.opsForSet().difference(key, otherKeys); } /** * key集合與otherKey集合的差集存儲到destKey中 * * @param key * @param otherKey * @param destKey * @return */ public Long sDifference(String key, String otherKey, String destKey) { return redisTemplate.opsForSet().differenceAndStore(key, otherKey, destKey); } /** * key集合與多個集合的差集存儲到destKey中 * * @param key * @param otherKeys * @param destKey * @return */ public Long sDifference(String key, Collection<String> otherKeys, String destKey) { return redisTemplate.opsForSet().differenceAndStore(key, otherKeys, destKey); } /** * 獲取集合所有元素 * * @param key * @return */ public Set<String> setMembers(String key) { return redisTemplate.opsForSet().members(key); } /** * 隨機獲取集合中的一個元素 * * @param key * @return */ public String sRandomMember(String key) { return redisTemplate.opsForSet().randomMember(key); } /** * 隨機獲取集合中count個元素 * * @param key * @param count * @return */ public List<String> sRandomMembers(String key, long count) { return redisTemplate.opsForSet().randomMembers(key, count); } /** * 隨機獲取集合中count個元素并且去除重復的 * * @param key * @param count * @return */ public Set<String> sDistinctRandomMembers(String key, long count) { return redisTemplate.opsForSet().distinctRandomMembers(key, count); } /** * * @param key * @param options * @return */ public Cursor<String> sScan(String key, ScanOptions options) { return redisTemplate.opsForSet().scan(key, options); } /**------------------zSet相關操作--------------------------------*/ /** * 添加元素,有序集合是按照元素的score值由小到大排列 * * @param key * @param value * @param score * @return */ public Boolean zAdd(String key, String value, double score) { return redisTemplate.opsForZSet().add(key, value, score); } /** * * @param key * @param values * @return */ public Long zAdd(String key, Set<TypedTuple<String>> values) { return redisTemplate.opsForZSet().add(key, values); } /** * * @param key * @param values * @return */ public Long zRemove(String key, Object... values) { return redisTemplate.opsForZSet().remove(key, values); } /** * 增加元素的score值,并返回增加后的值 * * @param key * @param value * @param delta * @return */ public Double zIncrementScore(String key, String value, double delta) { return redisTemplate.opsForZSet().incrementScore(key, value, delta); } /** * 返回元素在集合的排名,有序集合是按照元素的score值由小到大排列 * * @param key * @param value * @return 0表示第一位 */ public Long zRank(String key, Object value) { return redisTemplate.opsForZSet().rank(key, value); } /** * 返回元素在集合的排名,按元素的score值由大到小排列 * * @param key * @param value * @return */ public Long zReverseRank(String key, Object value) { return redisTemplate.opsForZSet().reverseRank(key, value); } /** * 獲取集合的元素, 從小到大排序 * * @param key * @param start * 開始位置 * @param end * 結束位置, -1查詢所有 * @return */ public Set<String> zRange(String key, long start, long end) { return redisTemplate.opsForZSet().range(key, start, end); } /** * 獲取集合元素, 并且把score值也獲取 * * @param key * @param start * @param end * @return */ public Set<TypedTuple<String>> zRangeWithScores(String key, long start, long end) { return redisTemplate.opsForZSet().rangeWithScores(key, start, end); } /** * 根據Score值查詢集合元素 * * @param key * @param min * 最小值 * @param max * 最大值 * @return */ public Set<String> zRangeByScore(String key, double min, double max) { return redisTemplate.opsForZSet().rangeByScore(key, min, max); } /** * 根據Score值查詢集合元素, 從小到大排序 * * @param key * @param min * 最小值 * @param max * 最大值 * @return */ public Set<TypedTuple<String>> zRangeByScoreWithScores(String key, double min, double max) { return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max); } /** * * @param key * @param min * @param max * @param start * @param end * @return */ public Set<TypedTuple<String>> zRangeByScoreWithScores(String key, double min, double max, long start, long end) { return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max, start, end); } /** * 獲取集合的元素, 從大到小排序 * * @param key * @param start * @param end * @return */ public Set<String> zReverseRange(String key, long start, long end) { return redisTemplate.opsForZSet().reverseRange(key, start, end); } /** * 獲取集合的元素, 從大到小排序, 并返回score值 * * @param key * @param start * @param end * @return */ public Set<TypedTuple<String>> zReverseRangeWithScores(String key, long start, long end) { return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end); } /** * 根據Score值查詢集合元素, 從大到小排序 * * @param key * @param min * @param max * @return */ public Set<String> zReverseRangeByScore(String key, double min, double max) { return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max); } /** * 根據Score值查詢集合元素, 從大到小排序 * * @param key * @param min * @param max * @return */ public Set<TypedTuple<String>> zReverseRangeByScoreWithScores( String key, double min, double max) { return redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max); } /** * * @param key * @param min * @param max * @param start * @param end * @return */ public Set<String> zReverseRangeByScore(String key, double min, double max, long start, long end) { return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max, start, end); } /** * 根據score值獲取集合元素數量 * * @param key * @param min * @param max * @return */ public Long zCount(String key, double min, double max) { return redisTemplate.opsForZSet().count(key, min, max); } /** * 獲取集合大小 * * @param key * @return */ public Long zSize(String key) { return redisTemplate.opsForZSet().size(key); } /** * 獲取集合大小 * * @param key * @return */ public Long zZCard(String key) { return redisTemplate.opsForZSet().zCard(key); } /** * 獲取集合中value元素的score值 * * @param key * @param value * @return */ public Double zScore(String key, Object value) { return redisTemplate.opsForZSet().score(key, value); } /** * 移除指定索引位置的成員 * * @param key * @param start * @param end * @return */ public Long zRemoveRange(String key, long start, long end) { return redisTemplate.opsForZSet().removeRange(key, start, end); } /** * 根據指定的score值的范圍來移除成員 * * @param key * @param min * @param max * @return */ public Long zRemoveRangeByScore(String key, double min, double max) { return redisTemplate.opsForZSet().removeRangeByScore(key, min, max); } /** * 獲取key和otherKey的并集并存儲在destKey中 * * @param key * @param otherKey * @param destKey * @return */ public Long zUnionAndStore(String key, String otherKey, String destKey) { return redisTemplate.opsForZSet().unionAndStore(key, otherKey, destKey); } /** * * @param key * @param otherKeys * @param destKey * @return */ public Long zUnionAndStore(String key, Collection<String> otherKeys, String destKey) { return redisTemplate.opsForZSet() .unionAndStore(key, otherKeys, destKey); } /** * 交集 * * @param key * @param otherKey * @param destKey * @return */ public Long zIntersectAndStore(String key, String otherKey, String destKey) { return redisTemplate.opsForZSet().intersectAndStore(key, otherKey, destKey); } /** * 交集 * * @param key * @param otherKeys * @param destKey * @return */ public Long zIntersectAndStore(String key, Collection<String> otherKeys, String destKey) { return redisTemplate.opsForZSet().intersectAndStore(key, otherKeys, destKey); } /** * * @param key * @param options * @return */ public Cursor<TypedTuple<String>> zScan(String key, ScanOptions options) { return redisTemplate.opsForZSet().scan(key, options); } }
測試
@SpringBootTest class Redis02SpringbootApplicationTests { @Autowired private RedisTemplate redisTemplate; @Test void contextLoads() { redisUtil.set("mykey", "我是大帥哥"); System.out.println(redisUtil.get("mykey")); } }
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
在原來的mysql配置基礎上,再加上redis的配置
spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/book?useSSL=false username: root password: root type: com.alibaba.druid.pool.DruidDataSource redis: # Redis數據庫索引(默認為0) database: 0 # host主機,默認為localhost host: 127.0.0.1 # 端口號,默認為6379 port: 6379 # 密碼,默認為空 password: # 連接池 jedis: pool: # 連接池最大連接數(使用負值表示沒有限制) max-active: 8 # 連接池中的最小空閑連接 min-idle: 0 # 連接池中的最大空閑連接 max-idle: 8 # 連接池最大阻塞等待時間(使用負值表示沒有限制) max-wait: -1 # 連接超時時間(毫秒) timeout: 5000
RedisConfiguration(序列化,必須配置,不然會json格式在redis中緩存會亂碼; Springboot1.x和2.x版本的序列化配置也不同,需要特別注意)
package com.hzf.config; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.lang.reflect.Method; @Configuration @EnableCaching public class RedisConfiguration extends CachingConfigurerSupport { /** * 緩存對象集合中,緩存是以 key-value 形式保存的。當不指定緩存的 key 時,SpringBoot 會使用 SimpleKeyGenerator 生成 key。 * @return */ @Bean public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); } }; } @Bean public CacheManager cacheManager(RedisConnectionFactory connectionFactory) { RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory).build(); return redisCacheManager; } /** * @return 返回類型 * @Description: 防止redis入庫序列化亂碼的問題 */ @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>(); redisTemplate.setConnectionFactory(redisConnectionFactory); redisTemplate.setKeySerializer(new StringRedisSerializer());//key序列化 redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(Object.class)); //value序列化 redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.afterPropertiesSet(); return redisTemplate; } }
注解 | 作用 |
---|---|
@Cacheable | 在方法執行前Spring先查看緩存中是否有數據,如果有數據,則直接返回緩存數據;沒有則調用方法并將方法返回值放進緩存。 |
@CachePut | 將方法的返回值放到緩存中。 |
@CacheEvict | 刪除緩存中的數據。 |
我這里將我的controller層某個方法返回的數據,上加上@Cacheable注解,也就是我們在第一次查詢后的數據將放入redis中,不會繼續再走mysql查詢了
關于@Cacheable注解的詳解,看別的博主所寫
https://blog.csdn.net/qq_31404603/article/details/88081039
//主頁推薦書籍 @Cacheable(value = "recommendbooks") @RequestMapping(value = "/recommendBook", method = {RequestMethod.GET}) public ServerResponse recommendBook(){ System.out.println("第一次查詢,會顯示這個信息"); bookService.updaterecommend(); List<Book> books = bookService.recommendBook(); if(books != null){ return ServerResponse.success("操作成功").data("recommendbooks",books); } return ServerResponse.error("操作失敗"); }
@EnableCaching 注解配置啟用緩存
啟動項目,訪問controller層的這個使用緩存的方法
網頁顯示的數據如下:
后端控制臺顯示:
之后不管怎么刷新請求,控制臺不在輸出那句話,且只查詢了一次
想要看到redis里面是否已經存入,我們可以直接通過命令行的方式
keys * 找到所有key get key 查找某個數據
也可以通過可視化工具進行查看
看第四part
項目中用到了redis,想查詢redis中的數據,一直想找一個可視化工具,今天發現了Redis Desktop Manager,試用了一下,很好用。
Redis Desktop Manager是開源的,可以在github下載到源碼。但是想在windows上用的話需要安裝包。
官網下載:https://redisdesktop.com/download
github地址:https://github.com/uglide/RedisDesktopManager/releases
官網地址下載需要訂閱,花錢的,還是算了吧。
晚上找到了一個免費下載的云盤:
百度網盤:http://pan.baidu.com/s/1kU8sY3P
exe文件,一路next就行了
連接redis服務器:這里連接的前提是你要連的redis服務已啟動
基于第三part實際項目的數據可以看到存入redis中的數據,如果要是刪除后,下次請求,還是先會找redis中是否有數據,有就直接返回,沒有的話重新從mysql查數據,再放去redis中。
到此,關于“redis使用實例分析”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。