SpringBoot學(xué)習(xí)(七)——springboot快速整合Redis

redis緩存

@[toc]

創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站制作、網(wǎng)站建設(shè)、峽江網(wǎng)絡(luò)推廣、成都微信小程序、峽江網(wǎng)絡(luò)營銷、峽江企業(yè)策劃、峽江品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供峽江建站搭建服務(wù),24小時服務(wù)熱線:13518219792,官方網(wǎng)址:bm7419.com

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供延邊朝鮮族網(wǎng)站建設(shè)、延邊朝鮮族做網(wǎng)站、延邊朝鮮族網(wǎng)站設(shè)計、延邊朝鮮族網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、延邊朝鮮族企業(yè)網(wǎng)站模板建站服務(wù),十載延邊朝鮮族做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。

市中網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項目制作,到程序開發(fā),運營維護(hù)。創(chuàng)新互聯(lián)從2013年成立到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。

成都創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)與策劃設(shè)計,泰和網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:泰和等地區(qū)。泰和做網(wǎng)站價格咨詢:13518219792

創(chuàng)新互聯(lián)2013年開創(chuàng)至今,先為新市等服務(wù)建站,新市等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為新市企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

創(chuàng)新互聯(lián)專注于中大型企業(yè)的網(wǎng)站制作、成都網(wǎng)站制作和網(wǎng)站改版、網(wǎng)站營銷服務(wù),追求商業(yè)策劃與數(shù)據(jù)分析、創(chuàng)意藝術(shù)與技術(shù)開發(fā)的融合,累計客戶上千多家,服務(wù)滿意度達(dá)97%。幫助廣大客戶順利對接上互聯(lián)網(wǎng)浪潮,準(zhǔn)確優(yōu)選出符合自己需要的互聯(lián)網(wǎng)運用,我們將一直專注品牌網(wǎng)站建設(shè)和互聯(lián)網(wǎng)程序開發(fā),在前進(jìn)的路上,與客戶一起成長!

簡介

redis是一個高性能的key-value數(shù)據(jù)庫

優(yōu)勢
  • 性能強,適合高度的讀寫操作(讀的速度是110000次/s,寫的速度是81000次/s )。

  • 支持較為豐富的數(shù)據(jù)類型(如二進(jìn)制的Strings, Lists, Hashes, Sets ,Ordered Sets)

  • 一定的事物能力(要么執(zhí)行成功要么完全不執(zhí)行)。
劣勢
  • 內(nèi)存數(shù)據(jù)庫訪問快,但也消耗硬件內(nèi)存資源

注:redis的單線程僅僅是說在網(wǎng)絡(luò)請求這一模塊上用一個請求處理客戶端的請求,但比如說持久化它就會重開一個線程/進(jìn)程去進(jìn)行處理。

引入redis緩存

點擊鏈接 下載 redis 的 window 版,下載好后,放入你平時放軟件的位置,解壓出來即安裝完成。(需要注意的是放入的文件目錄,當(dāng)前用戶要是可讀可寫的權(quán)限,比如window下的C:\Program Files (x86),這個目錄默認(rèn)只有管理員權(quán)限才能讀寫,redis運行時要在該目錄下實時寫入日志文件的,若無權(quán)限讀寫,則會操作不成功)

SpringBoot學(xué)習(xí)(七)—— springboot快速整合Redis

解壓出來的目錄如下所示,因為是Windows端的,可雙擊exe文件開啟客戶端,服務(wù)端。

SpringBoot學(xué)習(xí)(七)—— springboot快速整合Redis

因為這是 springboot 整合 redis 系列,所以雙擊打開服務(wù)端即可,別關(guān)閉打開的 cmd 窗口。
SpringBoot學(xué)習(xí)(七)—— springboot快速整合Redis

在pom.xml中加入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

在application.properties中添加

# Redis
#Redis服務(wù)器地址
spring.redis.host=127.0.0.1
#Redis服務(wù)器連接端口
spring.redis.port=6379
# Redis服務(wù)器連接密碼(默認(rèn)為空)
spring.redis.password=
#Redis數(shù)據(jù)庫索引(默認(rèn)為0)
spring.redis.database=0  
#連接池最大連接數(shù)(使用負(fù)值表示沒有限制)
spring.redis.jedis.pool.max-active=50
#連接池最大阻塞等待時間(使用負(fù)值表示沒有限制)
spring.redis.jedis.pool.max-wait=3000
#連接池中的最大空閑連接
spring.redis.jedis.pool.max-idle=20
#連接池中的最小空閑連接
spring.redis.jedis.pool.min-idle=5
#連接超時時間(毫秒)
spring.redis.timeout=4000

代碼實戰(zhàn)

新增代碼后的目錄如下所示

SpringBoot學(xué)習(xí)(七)—— springboot快速整合Redis

這里先說明一下主要類的作用,Springboot 提供了 RedisTemplate 類來操作 Redis,但是該類既無注釋解釋,命名規(guī)律也不夠 “望文生義” 。 所以寫了個 RedisUtil 來封裝一些常用的方法, RedisConfig 主要是將默認(rèn)的自動注入改為手動注入并加入序列化,避免一些中文亂碼問題。

這里特別說一說 RedisUtil 類,搜索 springboot 和 redis 的文章,這個需要自己封裝的類網(wǎng)上大多寫的非?;靵y,而且前后的封裝邏輯不一致, 我估計是某位博主從至少三個人那里復(fù)制粘貼糅合起來的,然后大家都跟著這位博主復(fù)制粘貼,反而成了熱門文章。我猜測大家看它是個工具類,而且六百行左右,大多沒有仔細(xì)琢磨,能簡單測試通過即可,但是稍加思考,發(fā)現(xiàn)問題真的不少,很容易誤導(dǎo)那些喜歡 “拿來主義” 的 “萌新” 。

雖然我這個系列也是快速上手系列,但我理解的快速上手,就是把讓人云里霧里的概念講直白,然后先暫時跳過那些需要深入的,避免剛?cè)胧值奈冯y情緒,把整個操作流程寫的清楚明白,給別人講一千遍道一萬句,不如讓他對著現(xiàn)成的程序跑一遍,我一直認(rèn)為:對著一片空白的屏幕學(xué)習(xí)程序,只會讓人愈加焦慮,最好的辦法是一邊運行,一邊深入。

所以我選取了 redis 五大類型中的String,Hash,Set,List,幾乎覆蓋每個類型,而 SortedSet 沒有選取是因為這是有序的Set,可以自己類比。工具類我統(tǒng)一提供的是取值,添加值,刪除值,命名規(guī)律絕對可以讓你 “望文生義” ,其實還有很多方法,這里我不全寫出來,是因為五大數(shù)據(jù)類型都有一堆方法,你不一定用得上,而且很占篇幅,在這里,授人以魚不如授人以漁,你仔細(xì)看看 RedisUtil 的工具類,就會發(fā)現(xiàn)規(guī)律,比如操作String,大多是先調(diào)用opsForValue()方法,操作Hash,大多先調(diào)用opsForHash()方法,把項目代碼下載到本地,idea里面點進(jìn)去,就能看到相關(guān)的一堆方法。工具類只是重新調(diào)用了,換了個名字,加了些邏輯處理。

別看是熱門文章就盲從,我舉幾個剛才說的問題,

SpringBoot學(xué)習(xí)(七)—— springboot快速整合Redis

SpringBoot學(xué)習(xí)(七)—— springboot快速整合Redis
還有這個的注釋說明風(fēng)格也不統(tǒng)一,給人的感覺看著容易云里霧里的,網(wǎng)上的工具類還用的都是這一個,真的是哭笑不得,大家抄來抄去,都是方案整合商,就不要……

下面開始代碼示范

RedisController.java

package com.example.controller;

import com.example.service.IRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("redis")
public class RedisController {

    @Autowired
    private IRedisService redisService;

    @RequestMapping("/redisString")
    public void redisString() {
        this.redisService.redisString();
    }

    @RequestMapping("/redisHash")
    public void redisHash() {
        this.redisService.redisHash();
    }

    @RequestMapping("/redisSet")
    public void redisSet() {
        this.redisService.redisSet();
    }

    @RequestMapping("/redisList")
    public void redisList() {
        this.redisService.redisList();
    }

    @RequestMapping("/redisSortedSet")
    public void redisSortedSet() {
        //有序的set,故而省略
    }

}

IRedisService.java

package com.example.service;

public interface IRedisService {

    void redisString();

    void redisHash();

    void redisSet();

    void redisList();

    void redisSortedSet();

}

RedisServiceIml.java

package com.example.service;

import com.example.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;

@Service("redisService")
public class RedisServiceIml implements IRedisService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private RedisUtil redisUtil;

    public void redisString() {
        //添加值
        redisUtil.stringSet("AAA", "這是一個String類型的值");
        //取值
        Object value = redisUtil.stringGet("AAA");
        System.out.println(value);
    }

    public void redisHash() {
        //添加值
        redisUtil.hashSet("BBB", "test1", "原h(huán)ash值1");
        redisUtil.hashSet("BBB", "test2", "新hash值1");
        redisUtil.hashSet("BBB", "test1", "原h(huán)ash值2");
        redisUtil.hashSet("BBB", "test2", "新hash值2");
        //取值
        Object value1 = redisUtil.hashGet("BBB", "test1");
        Object value2 = redisUtil.hashGet("BBB", "test2");
        System.out.println(value1);
        System.out.println(value2);
    }

    public void redisSet() {
        //添值
        redisUtil.setSet("CCC", "這是一組Set集合的第一個");
        redisUtil.setSet("CCC", "這是一組Set集合的第二個");
        redisUtil.setSet("CCC", "這是一組Set集合的第三個");
        //取值
        Set vaule = redisUtil.setGet("CCC");
        System.out.println(vaule);
    }

    public void redisList() {
        //添加值
        redisUtil.listSet("DDD", "這是一組List集合的第一個");
        redisUtil.listSet("DDD", "這是一組List集合的第二個");
        redisUtil.listSet("DDD", "這是一組List集合的第三個");
        //取值
        List list = redisUtil.listGet("DDD", 0, -1);
        System.out.println(list);
    }

    public void redisSortedSet() {
        //有序的set,故而省略
    }

}

RedisConfig.java

package com.example.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 配置連接工廠
        template.setConnectionFactory(factory);

        //序列化和反序列化redis中的值
        Jackson2JsonRedisSerializer jackson = new Jackson2JsonRedisSerializer(Object.class);
        //Java對象轉(zhuǎn)換成JSON結(jié)構(gòu)
        ObjectMapper objectMapper = new ObjectMapper();
        // 指定要序列化的域
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化輸入的類型
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson.setObjectMapper(objectMapper);

        // 值采用json序列化
        template.setValueSerializer(jackson);
        //使用StringRedisSerializer來序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());

        // 設(shè)置hash key和value序列化模式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jackson);
        template.afterPropertiesSet();

        return template;
    }

}

RedisUtil.java

package com.example.util;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

@Component
public class RedisUtil {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    //===============緩存相關(guān)方法===============

    //指定緩存失效時間
    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;
        }
    }

    //根據(jù)key獲取過期時間,返回0代表為永久有效
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    //===============數(shù)據(jù)類型為String的相關(guān)方法===============

    //根據(jù)key值獲取緩存值
    public Object stringGet(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    //根據(jù)key值存入數(shù)據(jù)類型為String的緩存值
    public boolean stringSet(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //根據(jù)key值存入數(shù)據(jù)類型為String的緩存值并設(shè)置時間
    public boolean stringSetWithTime(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //刪除緩存
    public void stringDelete(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }

    //===============數(shù)據(jù)類型為Hash的相關(guān)方法===============

    //根據(jù)key和item獲取緩存值
    public Object hashGet(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    //根據(jù)key和item存入數(shù)據(jù)類型為Hash的緩存值
    public boolean hashSet(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //根據(jù)key和item存入數(shù)據(jù)類型為Hash的緩存值并設(shè)置時間
    public boolean hashSetWithTime(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;
        }
    }

    //刪除緩存
    public void hashDelete(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }

    //===============數(shù)據(jù)類型為SET的相關(guān)方法===============

    //根據(jù)key值獲取緩存值
    public Set<Object> setGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //根據(jù)key值存入數(shù)據(jù)類型為SET的緩存值
    public long setSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    //根據(jù)key值存入數(shù)據(jù)類型為SET的緩存值并設(shè)置時間
    public long setSetWithTime(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;
        }
    }

    //刪除緩存
    public long setDelete(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    //===============數(shù)據(jù)類型為LIST的相關(guān)方法===============
    //獲取List緩存的內(nèi)容,從start到end,若從0到-1代表所有值
    public List<Object> listGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //根據(jù)key值存入數(shù)據(jù)類型為List的緩存值
    public boolean listSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //根據(jù)key值存入數(shù)據(jù)類型為List的緩存值并設(shè)置時間
    public boolean listSetWithTime(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;
        }
    }

    //刪除緩存
    public long listDelete(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

}

啟動項目后,瀏覽器輸入 http://localhost:8080/redis/redisString ,(前臺會報錯,是因為這個請求只是觸發(fā)后臺的業(yè)務(wù)邏輯,沒有前臺頁面展示)操作 String 類型的效果圖如下所示;

SpringBoot學(xué)習(xí)(七)—— springboot快速整合Redis

啟動項目后,瀏覽器輸入 http://localhost:8080/redis/redisHash ,操作 Hash 類型的效果圖如下所示;(注意一下,我之前代碼寫的是插入了四個值,只打印出來兩個,是因為如果key值和item值一樣,新來的值會覆蓋原來的值,對比圖和代碼,你品,你細(xì)品。)

SpringBoot學(xué)習(xí)(七)—— springboot快速整合Redis

啟動項目后,瀏覽器輸入 http://localhost:8080/redis/redisSet ,操作 Set 類型的效果圖如下所示;(Set是無序的)

SpringBoot學(xué)習(xí)(七)—— springboot快速整合Redis

啟動項目后,瀏覽器輸入 http://localhost:8080/redis/redisList ,操作 List 類型的效果圖如下所示;

SpringBoot學(xué)習(xí)(七)—— springboot快速整合Redis

注:如果是根據(jù)本文系列文章來的,因為一開始就配置好了spring security,所以記得將該地址配給所登錄的用戶?;蛘唛_一個超級管理員賬號,可以訪問項目的任意目錄,使用該管理員賬號訪問這些地址。

這是該學(xué)習(xí)系列的所有代碼,如果有不明白的,想自己實操豐富其中內(nèi)容的,可以下載到本地,

GitHub , 碼云

網(wǎng)站標(biāo)題:SpringBoot學(xué)習(xí)(七)——springboot快速整合Redis
本文地址:http://bm7419.com/article18/igchdp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、網(wǎng)站策劃、域名注冊、虛擬主機、網(wǎng)頁設(shè)計公司微信公眾號

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化