久久久噜噜噜久久熟女,久久久久久久久,国内精品,精品国产成人亚洲午夜福利,久久天堂av综合合色蜜桃网,好姑娘在线观看完整视频高清

首頁 > 時尚

SpringBoot整合Redis實現(xiàn)高并發(fā)數(shù)據(jù)緩存的示例講解 天天頭條

來源:腳本之家 時間:2023-06-24 16:03:49

目錄
什么是緩存為什么要用緩存Redis為什么這么快實現(xiàn)一個用戶信息的緩存方式一:利用RedisTemplate實現(xiàn) 導(dǎo)入依賴添加配置添加redis工具類及配置類service層controller層測試方式二:采用SpringBoot注解開啟緩存修改service層實現(xiàn)類代碼修改RedisConfig配置類

什么是緩存

緩存是?個高速數(shù)據(jù)交換的存儲器,使用它可以快速的訪問和操作數(shù)據(jù)。

舉個通俗的例子。

小明經(jīng)營著一家飯店,在剛開張的時候由于名氣不足,客源少,生意并不是很忙,平時沒事的時候就閑著,有客人來了再進廚房安排做菜。隨著飯店的日益發(fā)展,此時的飯店已經(jīng)不同往日,有著大量的穩(wěn)定客源,并且在某些節(jié)假日的時候甚至爆滿。按照以前的做法,那肯定是行不通了,在用餐高峰期的時候因為備餐慢導(dǎo)致了客戶的長時間等待,使得飯店的屢遭投訴。
為解決這一問題,小明想到了一個辦法,可以在空閑的時候,提前將熱門的菜做完后放入保溫柜,等用餐高峰期時再拿出來加熱后就可以直接上菜,就規(guī)避了短時間內(nèi)大量客源而導(dǎo)致的備餐慢的問題,通過這一方法,即使在高峰期,也能很好的應(yīng)對。


(資料圖片)

這就是緩存的本質(zhì),將熱點資源(高頻讀、低頻寫)提前放入離用戶最近、訪問速度更快的地方,以提高訪問速度。

為什么要用緩存

使用緩存后,效率會大大的提升,減少了不必要的資源消耗,提升了用戶體驗。

redis的特點:

redis支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保存在磁盤中,重啟的時候可以再次加在進行使用。redis不僅僅支持簡單的key-value類型的數(shù)據(jù),同時還提供list,set,zset,hash等數(shù)據(jù)結(jié)構(gòu)的儲存redis支持?jǐn)?shù)據(jù)的備份,即master-slave模式的數(shù)據(jù)備份

redis的優(yōu)勢:

性能極高——redis能讀得的速度是110000次/s,寫的速度是81000次/s。豐富的數(shù)據(jù)類型——redis支持二進制案例的Strings, Lists, Hashes, Sets 及 Ordered Sets 數(shù)據(jù)類型操作。原子——redis的所有操作都是原子性的,意思就是要么成功執(zhí)行要么失敗完全不執(zhí)行。單個操作是原子性的。多個操作也支持事務(wù),即原子性,通過multi和exec指令包起來。豐富的特性redis還支持publish/subscribe,通知,key過期等等特性

Redis為什么這么快

(1)完全基于內(nèi)存,數(shù)據(jù)存在內(nèi)存中,絕大部分請求是純粹的內(nèi)存操作,非??焖?,跟傳統(tǒng)的磁盤文件數(shù)據(jù)存儲相比,避免了通過磁盤IO讀取到內(nèi)存這部分的開銷。

(2)數(shù)據(jù)結(jié)構(gòu)簡單,對數(shù)據(jù)操作也簡單。Redis中的數(shù)據(jù)結(jié)構(gòu)是專門進行設(shè)計的,每種數(shù)據(jù)結(jié)構(gòu)都有一種或多種數(shù)據(jù)結(jié)構(gòu)來支持。Redis正是依賴這些靈活的數(shù)據(jù)結(jié)構(gòu),來提升讀取和寫入的性能。

(3)采用單線程,省去了很多上下文切換的時間以及CPU消耗,不存在競爭條件,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,也不會出現(xiàn)死鎖而導(dǎo)致的性能消耗。

(4)使用基于IO多路復(fù)用機制的線程模型,可以處理并發(fā)的鏈接。

實現(xiàn)一個用戶信息的緩存

數(shù)據(jù)庫表結(jié)構(gòu):

CREATE TABLE `blade_user` (
  `id` bigint(20) NOT NULL COMMENT "主鍵",
  `tenant_id` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT "000000" COMMENT "租戶ID",
  `code` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "用戶編號",
  `user_type` int(11) DEFAULT NULL COMMENT "用戶平臺",
  `account` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "賬號",
  `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "密碼",
  `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "昵稱",
  `real_name` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "真名",
  `avatar` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "頭像",
  `email` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "郵箱",
  `phone` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "手機",
  `birthday` datetime DEFAULT NULL COMMENT "生日",
  `sex` int(11) DEFAULT NULL COMMENT "性別",
  `role_id` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "角色id",
  `dept_id` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "部門id",
  `post_id` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "崗位id",
  `create_user` bigint(20) DEFAULT NULL COMMENT "創(chuàng)建人",
  `create_dept` bigint(20) DEFAULT NULL COMMENT "創(chuàng)建部門",
  `create_time` datetime DEFAULT NULL COMMENT "創(chuàng)建時間",
  `update_user` bigint(20) DEFAULT NULL COMMENT "修改人",
  `update_time` datetime DEFAULT NULL COMMENT "修改時間",
  `status` int(11) DEFAULT NULL COMMENT "狀態(tài)",
  `is_deleted` int(11) DEFAULT "0" COMMENT "是否已刪除",
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT="用戶表";

方式一:利用RedisTemplate實現(xiàn) 導(dǎo)入依賴

完整pom.xml文件:



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.7.8
         
    
    com.redis.demo
    springboot-redis
    0.0.1-SNAPSHOT
    springboot-redis
    Demo project for Spring Boot
    
        1.8
    
    

        
            org.springframework.boot
            spring-boot-starter-web
        


        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
        
            com.baomidou
            mybatis-plus-boot-starter
            3.4.2
        
        
            org.springframework.boot
            spring-boot-starter-data-redis
        

        
        
            mysql
            mysql-connector-java
            8.0.15
        

       
        
            cn.hutool
            hutool-all
            5.8.5
        
        
            com.alibaba
            fastjson
            1.2.41
        

        
            org.springframework.boot
            spring-boot-starter-cache
        

    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
        
    




添加配置

application.yml文件:

server:
  port: 8081

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://3.129.36.183:3306/test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: root
  #redis
  redis:
    host: 3.129.36.183
    #Redis服務(wù)器連接端口
    port: 6379
    #Redis服務(wù)器連接密碼
    password: 123456

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #開啟sql日志
    # 將帶有下劃線的表字段映射為駝峰格式的實體類屬性
    map-underscore-to-camel-case: true
  #配置類型別名所對應(yīng)的包
  type-aliases-package: com.redis.demo.entity
  #配置SQL輸出語句com.winsun.dataclean.mapper
  mapper-locations: com/redis/demo/dao/*.xml

添加redis工具類及配置類

RedisUtils:

package com.redis.demo.utils;

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

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

/**
 * Redis工具類
 *
 * @author
 */
@Component
public class RedisUtils {


    @Autowired
    private 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;
        }
    }

    /**
     * 根據(jù)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;
        }
    }

    /**
     * 普通緩存放入并設(shè)置時間
     *
     * @param key   鍵
     * @param value 值
     * @param time  時間(秒) time要大于0 如果time小于等于0 將設(shè)置無限期
     * @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 delta 要增加幾(大于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 delta 要減少幾(小于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對應(yīng)的所有鍵值
     *
     * @param key 鍵
     * @return 對應(yīng)的多個鍵值
     */
    public Map hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     *
     * @param key 鍵
     * @param map 對應(yīng)多個鍵值
     * @return true 成功 false 失敗
     */
    public boolean hmset(String key, Map map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * HashSet 并設(shè)置時間
     *
     * @param key  鍵
     * @param map  對應(yīng)多個鍵值
     * @param time 時間(秒)
     * @return true成功 false失敗
     */
    public boolean hmset(String key, Map 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表中放入數(shù)據(jù),如果不存在將創(chuàng)建
     *
     * @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表中放入數(shù)據(jù),如果不存在將創(chuàng)建
     *
     * @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遞增 如果不存在,就會創(chuàng)建一個 并把新增后的值返回
     *
     * @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=============================

    /**
     * 根據(jù)key獲取Set中的所有值
     *
     * @param key 鍵
     * @return
     */
    public Set sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根據(jù)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;
        }
    }

    /**
     * 將數(shù)據(jù)放入set緩存
     *
     * @param key    鍵
     * @param values 值 可以是多個
     * @return 成功個數(shù)
     */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 將set數(shù)據(jù)放入緩存
     *
     * @param key    鍵
     * @param time   時間(秒)
     * @param values 值 可以是多個
     * @return 成功個數(shù)
     */
    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 移除的個數(shù)
     */
    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緩存的內(nèi)容
     *
     * @param key   鍵
     * @param start 開始
     * @param end   結(jié)束 0 到 -1代表所有值
     * @return
     */
    public List 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倒數(shù)第二個元素,依次類推
     * @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 值
     * @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 值
     * @return
     */
    public boolean lSet(String key, List 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 value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0)
                expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根據(jù)索引修改list中的某條數(shù)據(jù)
     *
     * @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 移除的個數(shù)
     */
    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;
        }
    }
}

RedisConfig:

package com.redis.demo.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.redis.demo.utils.MapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.interceptor.KeyGenerator;
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.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

import javax.annotation.PostConstruct;
import java.util.Map;

/**
 * @Author: laz
 * @CreateTime: 2023-02-20  11:55
 * @Version: 1.0
 *
 * 序列化
 */
@Configuration
public class RedisConfig {


    @Autowired
    private RedisTemplate redisTemplate;

    @PostConstruct
    public void init() {
        initRedisTemplate();
    }

    private void initRedisTemplate() {
        RedisSerializer stringSerializer = redisTemplate.getStringSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(stringSerializer);
    }
}

開發(fā)mapper接口

package com.redis.demo.dao;


import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.redis.demo.entity.BladeUser;

/**
 * 

* 用戶表 Mapper 接口 *

* * @author laz * @since 2023-03-09 */ public interface BladeUserMapper extends BaseMapper { }

service層

IBladeUserService:

package com.redis.demo.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.redis.demo.entity.BladeUser;
import com.redis.demo.result.DealResult;

/**
 * 

* 用戶表 服務(wù)類 *

* * @author laz * @since 2023-03-09 */ public interface IBladeUserService extends IService { DealResult getById(Long id); }

BladeUserServiceImpl:

package com.redis.demo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.redis.demo.constant.RedisConstants;
import com.redis.demo.dao.BladeUserMapper;
import com.redis.demo.entity.BladeUser;
import com.redis.demo.result.DealResult;
import com.redis.demo.service.IBladeUserService;
import com.redis.demo.status.CacheNameStatus;
import com.redis.demo.utils.RedisUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

/**
 * 

* 用戶表 服務(wù)實現(xiàn)類 *

* * @author laz * @since 2023-03-09 */ @Service public class BladeUserServiceImpl extends ServiceImpl implements IBladeUserService { @Autowired private RedisUtils redisUtils; @Override public DealResult getById(Long id) { String userKey = RedisConstants.CACHE_USER_KEY+id; Object user = redisUtils.get(userKey); if (!ObjectUtils.isEmpty(user)){ return DealResult.data(JSONUtil.toBean(JSONUtil.toJsonStr(user),BladeUser.class)); } BladeUser bladeUser = baseMapper.selectById(id); redisUtils.set(userKey, JSON.toJSONString(bladeUser)); return DealResult.data(bladeUser); } }

controller層

package com.redis.demo.controller;
import com.redis.demo.result.DealResult;
import com.redis.demo.service.IBladeUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;

/**
 * 

* 用戶表 前端控制器 *

* * @author laz * @since 2023-03-09 */ @RestController @RequestMapping("/bladeUser") public class BladeUserController { @Autowired private IBladeUserService bladeUserService; @RequestMapping("getById/{id}") public DealResult getById(@PathVariable("id")Long id){ return bladeUserService.getById(id); } }

測試

啟動項目,使用postman訪問該接口,連續(xù)請求兩次,觀察響應(yīng)時長:

第一次:

第二次:

可以看到,第一次3.34s,第二次43ms,效率明顯提高!

方式二:采用SpringBoot注解開啟緩存

以方式一為準(zhǔn)

在啟動類添加@EnableCaching注解

修改service層實現(xiàn)類代碼

package com.redis.demo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.redis.demo.constant.RedisConstants;
import com.redis.demo.dao.BladeUserMapper;
import com.redis.demo.entity.BladeUser;
import com.redis.demo.result.DealResult;
import com.redis.demo.service.IBladeUserService;
import com.redis.demo.status.CacheNameStatus;
import com.redis.demo.utils.RedisUtils;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

/**
 * 

* 用戶表 服務(wù)實現(xiàn)類 *

* * @author laz * @since 2023-03-09 */ @Service public class BladeUserServiceImpl extends ServiceImpl implements IBladeUserService { @Autowired private RedisUtils redisUtils; // @Override // public DealResult getById(Long id) { // // String userKey = RedisConstants.CACHE_USER_KEY+id; // Object user = redisUtils.get(userKey); // if (!ObjectUtils.isEmpty(user)){ // // return DealResult.data(JSONUtil.toBean(JSONUtil.toJsonStr(user),BladeUser.class)); // } // // BladeUser bladeUser = baseMapper.selectById(id); // redisUtils.set(userKey, JSON.toJSONString(bladeUser)); // return DealResult.data(bladeUser); // } @Cacheable(cacheNames = CacheNameStatus.BLADE_USER,keyGenerator = CacheNameStatus.KEY_GENERATOR) @Override public DealResult getById(Long id) { BladeUser bladeUser = baseMapper.selectById(id); return DealResult.data(bladeUser); } }

修改RedisConfig配置類

在配置類中添加自定義KeyGenerator

/**
     * 自定義KeyGenerator
     * @return
     */
    @Bean
    public KeyGenerator simpleKeyGenerator() {
        return (o, method, objects) -> {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(o.getClass().getSimpleName());
            stringBuilder.append(".");
            stringBuilder.append(method.getName());
            stringBuilder.append("[");
            for (Object obj : objects) {
                if(obj.toString().indexOf("Vo@")!= -1)
                {
                    Map map = MapUtil.getAttrFromModel(obj);
                    stringBuilder.append("[");
                    for(String item:map.keySet())
                    {
                        stringBuilder.append(",");
                        stringBuilder.append(map.get(item));
                    }

                    stringBuilder.append(",");
                    stringBuilder.deleteCharAt(stringBuilder.length() - 1);

                    stringBuilder.append("]");

                }
                else {
                    stringBuilder.append(obj);
                    stringBuilder.append(",");
                }

            }

            stringBuilder.append("]");
            return stringBuilder.toString();
        };
    }

:關(guān)于 @Cacheable注解的參數(shù),不懂的可以點擊查看。

重啟項目,再次訪問以上接口,觀察響應(yīng)時間:

第一次:

第二次:

可以看到,第一次2.52s,第二次44ms,效率明顯提高!

通過Redis可視化工具觀察緩存數(shù)據(jù):

通過觀察緩存數(shù)據(jù)大小可知:方式一449字節(jié),方式二976字節(jié),如果從內(nèi)存占用大小的角度考慮,博主認為使用RedisTemplate方式做緩存更合適,因為這種方式所占內(nèi)存相對較少。

以上就是該篇文章的所有內(nèi)容,代碼已上傳至git:https://gitee.com/lianaozhe/springboot-redis.git

到此這篇關(guān)于SpringBoot整合Redis實現(xiàn)高并發(fā)數(shù)據(jù)緩存的文章就介紹到這了,更多相關(guān)SpringBoot Redis高并發(fā)數(shù)據(jù)緩存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)稿件

SpringBoot整合Redis實現(xiàn)高并發(fā)數(shù)據(jù)緩存的示例講解 天天頭條

全球看熱訊:古裝廠牌到全能玩家,年均爆款的西嘻影業(yè)提供了影視公司的生存法

【旗艦】7.5見?紅魔8S Pro發(fā)布時間曝光 國內(nèi)首臺8G2超頻版 全球百事通

廈門社保要交滿多少年,廈門社保繳費年限如何法規(guī)的

烏克蘭基輔市遭導(dǎo)彈襲擊 已致3人死亡_焦點信息

世界新資訊:北京市氣象臺發(fā)布高溫紅色預(yù)警信號 最高氣溫可達37-40℃

世界信息:上海2022年退休工資調(diào)整細則

萬圣節(jié)門鈴和禮物創(chuàng)意,男生浪漫到底可行嗎?如何為這個節(jié)日增添驚喜?知乎專家來為你解答!

風(fēng)吹十里荷花香 “蓮”通鄉(xiāng)村“致富路”

美媒稱波蘭曾作為“北溪”爆炸行動基地 波蘭:完全不屬實!

世界新動態(tài):全國鐵路今天預(yù)計發(fā)送旅客1515萬人次

燃氣閥門怎樣操作,你都了解嗎?請收藏轉(zhuǎn)發(fā)!

【當(dāng)前熱聞】戒糖就是甜的不吃嗎

農(nóng)業(yè)機械化有力保障夏糧收獲

全球資訊:三天漲超20%!工業(yè)富聯(lián)最新發(fā)聲

最新消息:外三元毛豬

速遞!白玉蘭視帝視后出爐,雷佳音打敗張譯獲得視帝,吳越視后實至名歸

我二次元的朋友們(8)|天天微資訊

可以接受友情變愛情的三個星座,日久生情 每日消息

六月第4期:六大策略組合表現(xiàn):寬信用本周收益率為0.5%

保護知識產(chǎn)權(quán)激發(fā)創(chuàng)新活力

端午節(jié)了還沒學(xué)會包粽子?用VR試試,幫你成為特級廚師!

天天即時看!CK3歷史人物維基翻譯(166):弗沙塔將軍

環(huán)球今頭條!美媒:福特擬進行新一輪裁員,主要針對美國正式員工

端午假期廈門舉辦各式活動 市民游客感受傳統(tǒng)節(jié)日魅力

廈門天馬高世代生產(chǎn)線項目順利推進

我國最長深水油氣管道進入調(diào)試階段

今日精選:風(fēng)吹十里荷花香 “蓮”通鄉(xiāng)村“致富路”

終究走到了這一步,烏克蘭干了一件荒唐的事

薛麗萍家庭被評為第三屆江蘇省文明家庭