日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Spring Boot 整合Redis 实现缓存

發布時間:2023/11/27 生活经验 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Boot 整合Redis 实现缓存 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

本文提綱 一、緩存的應用場景 二、更新緩存的策略 三、運行?springboot-mybatis-redis?工程案例 四、springboot-mybatis-redis?工程代碼配置詳解 運行環境: Mac OS 10.12.x JDK 8 + Redis 3.2.8 Spring Boot 1.5.1.RELEASE

一、緩存的應用場景

什么是緩存? 在互聯網場景下,尤其 2C 端大流量場景下,需要將一些經常展現和不會頻繁變更的數據,存放在存取速率更快的地方。緩存就是一個存儲器,在技術選型中,常用 Redis 作為緩存數據庫。緩存主要是在獲取資源方便性能優化的關鍵方面。 Redis 是一個高性能的 key-value 數據庫。GitHub 地址:https://github.com/antirez/redis?。Github 是這么描述的: Redis is an in-memory database that persists on disk. The data model is key-value, but many different kind of values are supported: Strings, Lists, Sets, Sorted Sets, Hashes, HyperLogLogs, Bitmaps. 緩存的應用場景有哪些呢? 比如常見的電商場景,根據商品 ID 獲取商品信息時,店鋪信息和商品詳情信息就可以緩存在 Redis,直接從 Redis 獲取。減少了去數據庫查詢的次數。但會出現新的問題,就是如何對緩存進行更新?這就是下面要講的。

二、更新緩存的策略

參考《緩存更新的套路》http://coolshell.cn/articles/17416.html,緩存更新的模式有四種:Cache aside, Read through, Write through, Write behind caching。 這里我們使用的是 Cache Aside 策略,從三個維度:(摘自 耗子叔叔博客) 失效:應用程序先從cache取數據,沒有得到,則從數據庫中取數據,成功后,放到緩存中。 命中:應用程序從cache中取數據,取到后返回。 更新:先把數據存到數據庫中,成功后,再讓緩存失效。 大致流程如下: 獲取商品詳情舉例 a. 從商品 Cache 中獲取商品詳情,如果存在,則返回獲取 Cache 數據返回。 b. 如果不存在,則從商品 DB 中獲取。獲取成功后,將數據存到 Cache 中。則下次獲取商品詳情,就可以從 Cache 就可以得到商品詳情數據。 c. 從商品 DB 中更新或者刪除商品詳情成功后,則從緩存中刪除對應商品的詳情緩存

三、運行?springboot-mybatis-redis?工程案例

git clone 下載工程?springboot-learning-example ,項目地址見 GitHub –?https://github.com/JeffLi1993/springboot-learning-example。 下面開始運行工程步驟(Quick Start): 1.數據庫和 Redis 準備 a.創建數據庫 springbootdb:
1 CREATE DATABASE springbootdb;
b.創建表 city :(因為我喜歡徒步)
1 2 3 4 5 6 7 8 DROP TABLE IF EXISTS? `city`; CREATE TABLE `city` ( ??`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '城市編號', ??`province_id` int(10) unsigned? NOT NULL COMMENT '省份編號', ??`city_name` varchar(25) DEFAULT NULL COMMENT '城市名稱', ??`description` varchar(25) DEFAULT NULL COMMENT '描述', ??PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
c.插入數據
1 INSERT city VALUES (1 ,1,'溫嶺市','BYSocket 的家在溫嶺。');
d.本地安裝 Redis 詳見寫過的文章《 Redis 安裝?》http://www.bysocket.com/?p=917 2.?springboot-mybatis-redis 工程項目結構介紹
1 2 3 4 5 6 7 springboot-mybatis-redis?工程項目結構如下圖所示: org.spring.springboot.controller - Controller 層 org.spring.springboot.dao - 數據操作層 DAO org.spring.springboot.domain - 實體類 org.spring.springboot.service - 業務邏輯層 Application - 應用啟動類 application.properties - 應用配置文件,應用啟動會自動讀取配置
3.改數據庫配置 打開 application.properties 文件, 修改相應的數據源配置,比如數據源地址、賬號、密碼等。 (如果不是用 MySQL,自行添加連接驅動 pom,然后修改驅動名配置。) 4.編譯工程 在項目根目錄 springboot-learning-example,運行 maven 指令:
1 mvn clean install
5.運行工程 右鍵運行?springboot-mybatis-redis 工程 Application 應用啟動類的 main 函數。 項目運行成功后,這是個?HTTP OVER JSON 服務項目。所以用 postman 工具可以如下操作 根據 ID,獲取城市信息 GET?http://127.0.0.1:8080/api/city/1 再請求一次,獲取城市信息會發現數據獲取的耗時快了很多。服務端 Console 輸出的日志:
1 2 2017-04-13 18:29:00.273? INFO 13038 --- [nio-8080-exec-1] o.s.s.service.impl.CityServiceImpl? ? ? ?: CityServiceImpl.findCityById() : 城市插入緩存 >> City{id=12, provinceId=3, cityName='三亞', description='水好,天藍'} 2017-04-13 18:29:03.145? INFO 13038 --- [nio-8080-exec-2] o.s.s.service.impl.CityServiceImpl? ? ? ?: CityServiceImpl.findCityById() : 從緩存中獲取了城市 >> City{id=12, provinceId=3, cityName='三亞', description='水好,天藍'}
可見,第一次是從數據庫 DB 獲取數據,并插入緩存,第二次直接從緩存中取。 更新城市信息 PUT?http://127.0.0.1:8080/api/city 刪除城市信息 DELETE http://127.0.0.1:8080/api/city/2 這兩種操作中,如果緩存有對應的數據,則刪除緩存。服務端 Console 輸出的日志:
1 2017-04-13 18:29:52.248? INFO 13038 --- [nio-8080-exec-9] o.s.s.service.impl.CityServiceImpl? ? ? ?: CityServiceImpl.deleteCity() : 從緩存中刪除城市 ID >> 12

四、springboot-mybatis-redis?工程代碼配置詳解

這里,我強烈推薦?注解 的方式實現對象的緩存。但是這里為了更好說明緩存更新策略。下面講講工程代碼的實現。 pom.xml 依賴配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 <?xml version="1.0"?encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ?????????xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> ????<modelVersion>4.0.0</modelVersion> ????<groupId>springboot</groupId> ????<artifactId>springboot-mybatis-redis</artifactId> ????<version>0.0.1-SNAPSHOT</version> ????<name>springboot-mybatis-redis :: 整合 Mybatis 并使用 Redis 作為緩存</name> ????<!-- Spring Boot 啟動父依賴 --> ????<parent> ????????<groupId>org.springframework.boot</groupId> ????????<artifactId>spring-boot-starter-parent</artifactId> ????????<version>1.5.1.RELEASE</version> ????</parent> ????<properties> ????????<mybatis-spring-boot>1.2.0</mybatis-spring-boot> ????????<mysql-connector>5.1.39</mysql-connector> ????????<spring-boot-starter-redis-version>1.3.2.RELEASE</spring-boot-starter-redis-version> ????</properties> ????<dependencies> ????????<!-- Spring Boot Reids 依賴 --> ????????<dependency> ????????????<groupId>org.springframework.boot</groupId> ????????????<artifactId>spring-boot-starter-redis</artifactId> ????????????<version>${spring-boot-starter-redis-version}</version> ????????</dependency> ????????<!-- Spring Boot Web 依賴 --> ????????<dependency> ????????????<groupId>org.springframework.boot</groupId> ????????????<artifactId>spring-boot-starter-web</artifactId> ????????</dependency> ????????<!-- Spring Boot Test 依賴 --> ????????<dependency> ????????????<groupId>org.springframework.boot</groupId> ????????????<artifactId>spring-boot-starter-test</artifactId> ????????????<scope>test</scope> ????????</dependency> ????????<!-- Spring Boot Mybatis 依賴 --> ????????<dependency> ????????????<groupId>org.mybatis.spring.boot</groupId> ????????????<artifactId>mybatis-spring-boot-starter</artifactId> ????????????<version>${mybatis-spring-boot}</version> ????????</dependency> ????????<!-- MySQL 連接驅動依賴 --> ????????<dependency> ????????????<groupId>mysql</groupId> ????????????<artifactId>mysql-connector-java</artifactId> ????????????<version>${mysql-connector}</version> ????????</dependency> ????????<!-- Junit --> ????????<dependency> ????????????<groupId>junit</groupId> ????????????<artifactId>junit</artifactId> ????????????<version>4.12</version> ????????</dependency> ????</dependencies> </project>
包括了?Spring Boot Reids 依賴、 MySQL 依賴和 Mybatis 依賴。 在 application.properties 應用配置文件,增加 Redis 相關配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ## 數據源配置 spring.datasource.url=jdbc:mysql://localhost:3306/springbootdb?useUnicode=true&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver ## Mybatis 配置 mybatis.typeAliasesPackage=org.spring.springboot.domain mybatis.mapperLocations=classpath:mapper/*.xml ## Redis 配置 ## Redis數據庫索引(默認為0) spring.redis.database=0 ## Redis服務器地址 spring.redis.host=127.0.0.1 ## Redis服務器連接端口 spring.redis.port=6379 ## Redis服務器連接密碼(默認為空) spring.redis.password= ## 連接池最大連接數(使用負值表示沒有限制) spring.redis.pool.max-active=8 ## 連接池最大阻塞等待時間(使用負值表示沒有限制) spring.redis.pool.max-wait=-1 ## 連接池中的最大空閑連接 spring.redis.pool.max-idle=8 ## 連接池中的最小空閑連接 spring.redis.pool.min-idle=0 ## 連接超時時間(毫秒) spring.redis.timeout=0
詳細解釋可以參考注釋。對應的配置類:org.springframework.boot.autoconfigure.data.redis.RedisProperties CityRestController 控制層依舊是 Restful 風格的,詳情可以參考《Springboot 實現 Restful 服務,基于 HTTP / JSON 傳輸》。?http://www.bysocket.com/?p=1627?domain 對象 City 必須實現序列化,因為需要將對象序列化后存儲到 Redis。如果沒實現?Serializable ,控制臺會爆出以下異常:
1 2 Serializable java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type
City.java 城市對象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 package org.spring.springboot.domain; import?java.io.Serializable; /** ?* 城市實體類 ?* ?* Created by bysocket on 07/02/2017. ?*/ public class City implements Serializable { ????private static final long serialVersionUID = -1L; ????/** ?????* 城市編號 ?????*/ ????private Long id; ????/** ?????* 省份編號 ?????*/ ????private Long provinceId; ????/** ?????* 城市名稱 ?????*/ ????private String cityName; ????/** ?????* 描述 ?????*/ ????private String description; ????public Long getId() { ????????return?id; ????} ????public void setId(Long id) { ????????this.id?= id; ????} ????public Long getProvinceId() { ????????return?provinceId; ????} ????public void setProvinceId(Long provinceId) { ????????this.provinceId = provinceId; ????} ????public String getCityName() { ????????return?cityName; ????} ????public void setCityName(String cityName) { ????????this.cityName = cityName; ????} ????public String getDescription() { ????????return?description; ????} ????public void setDescription(String description) { ????????this.description = description; ????} ????@Override ????public String toString() { ????????return?"City{"?+ ????????????????"id="?+ id?+ ????????????????", provinceId="?+ provinceId + ????????????????", cityName='"?+ cityName + '\''?+ ????????????????", description='"?+ description + '\''?+ ????????????????'}'; ????} }
如果需要自定義序列化實現,只要實現?RedisSerializer 接口去實現即可,然后在使用 RedisTemplate.setValueSerializer 方法去設置你實現的序列化實現。 主要還是城市業務邏輯實現類 CityServiceImpl.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 package org.spring.springboot.service.impl; import?org.slf4j.Logger; import?org.slf4j.LoggerFactory; import?org.spring.springboot.dao.CityDao; import?org.spring.springboot.domain.City; import?org.spring.springboot.service.CityService; import?org.springframework.beans.factory.annotation.Autowired; import?org.springframework.data.redis.core.RedisTemplate; import?org.springframework.data.redis.core.StringRedisTemplate; import?org.springframework.data.redis.core.ValueOperations; import?org.springframework.stereotype.Service; import?java.util.List; import?java.util.concurrent.TimeUnit; /** ?* 城市業務邏輯實現類 ?* <p> ?* Created by bysocket on 07/02/2017. ?*/ @Service public class CityServiceImpl implements CityService { ????private static final Logger LOGGER = LoggerFactory.getLogger(CityServiceImpl.class); ????@Autowired ????private CityDao cityDao; ????@Autowired ????private RedisTemplate redisTemplate; ????/** ?????* 獲取城市邏輯: ?????* 如果緩存存在,從緩存中獲取城市信息 ?????* 如果緩存不存在,從 DB 中獲取城市信息,然后插入緩存 ?????*/ ????public City findCityById(Long id) { ????????//?從緩存中獲取城市信息 ????????String key = "city_"?+ id; ????????ValueOperations<String, City> operations = redisTemplate.opsForValue(); ????????//?緩存存在 ????????boolean hasKey = redisTemplate.hasKey(key); ????????if?(hasKey) { ????????????City city = operations.get(key); ????????????LOGGER.info("CityServiceImpl.findCityById() : 從緩存中獲取了城市 >> "?+ city.toString()); ????????????return?city; ????????} ????????//?從 DB 中獲取城市信息 ????????City city = cityDao.findById(id); ????????//?插入緩存 ????????operations.set(key, city, 10, TimeUnit.SECONDS); ????????LOGGER.info("CityServiceImpl.findCityById() : 城市插入緩存 >> "?+ city.toString()); ????????return?city; ????} ????@Override ????public Long saveCity(City city) { ????????return?cityDao.saveCity(city); ????} ????/** ?????* 更新城市邏輯: ?????* 如果緩存存在,刪除 ?????* 如果緩存不存在,不操作 ?????*/ ????@Override ????public Long updateCity(City city) { ????????Long ret = cityDao.updateCity(city); ????????//?緩存存在,刪除緩存 ????????String key = "city_"?+ city.getId(); ????????boolean hasKey = redisTemplate.hasKey(key); ????????if?(hasKey) { ????????????redisTemplate.delete(key); ????????????LOGGER.info("CityServiceImpl.updateCity() : 從緩存中刪除城市 >> "?+ city.toString()); ????????} ????????return?ret; ????} ????@Override ????public Long deleteCity(Long id) { ????????Long ret = cityDao.deleteCity(id); ????????//?緩存存在,刪除緩存 ????????String key = "city_"?+ id; ????????boolean hasKey = redisTemplate.hasKey(key); ????????if?(hasKey) { ????????????redisTemplate.delete(key); ????????????LOGGER.info("CityServiceImpl.deleteCity() : 從緩存中刪除城市 ID >> "?+ id); ????????} ????????return?ret; ????} }
首先這里注入了?RedisTemplate 對象。聯想到 Spring 的 JdbcTemplate ,RedisTemplate 封裝了 RedisConnection,具有連接管理,序列化和 Redis 操作等功能。還有針對 String 的支持對象?StringRedisTemplate。 Redis?操作視圖接口類用的是?ValueOperations,對應的是 Redis String/Value 操作。還有其他的操作視圖,ListOperations、SetOperations、ZSetOperations 和 HashOperations 。ValueOperations 插入緩存是可以設置失效時間,這里設置的失效時間是 10 s。 回到更新緩存的邏輯 a. findCityById 獲取城市邏輯: 如果緩存存在,從緩存中獲取城市信息 如果緩存不存在,從 DB 中獲取城市信息,然后插入緩存 b. deleteCity 刪除 / updateCity 更新城市邏輯: 如果緩存存在,刪除 如果緩存不存在,不操作 其他不明白的,可以 git clone 下載工程 springboot-learning-example ,工程代碼注解很詳細。 https://github.com/JeffLi1993/springboot-learning-example。

五、小結

本文涉及到 Spring Boot 在使用 Redis 緩存時,一個是緩存對象需要序列化,二個是緩存更新策略是如何的。

轉載于:https://www.cnblogs.com/Soy-technology/p/11025089.html

總結

以上是生活随笔為你收集整理的Spring Boot 整合Redis 实现缓存的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 超能一家人电影免费喜剧在线观看 | 嘿咻视频在线观看 | 女人免费视频 | 超碰在线中文字幕 | 欧美黑人又粗又大高潮喷水 | 亚洲免费av在线 | 中文字幕在线视频观看 | 国产精品成人在线观看 | 亚洲一区二区三区人妻 | 国产免费一区二区三区免费视频 | 色狠 | 美女在线观看www | 饥渴丰满的少妇喷潮 | 国产天天射 | 国产免费看av | a级黄色在线观看 | av集中营| 国内精品嫩模av私拍在线观看 | 成年人黄网站 | 天天干夜夜骑 | 国产毛片av | 免费高清视频在线观看 | 亚洲综合五区 | 日本污网站 | 欧美顶级少妇做爰 | 国产乱仑视频 | 中文字幕一区二区三区四区视频 | 3p视频在线 | 国产无限制自拍 | 最近国语视频在线观看免费播放 | 超碰男人天堂 | caoporen超碰 | 正在播放老肥熟妇露脸 | 免费一区二区三区 | 日韩av在线一区二区三区 | 精品无人区无码乱码毛片国产 | 蜜臀网在线 | 欧美丰满老妇熟乱xxxxyyy | 爱福利视频广场 | 中文字幕在线观看高清 | 日本 奴役 捆绑 受虐狂xxxx | 亚洲卡一卡二卡三 | 欧美日韩一区二区在线观看视频 | 情侣作爱视频网站 | 青青草手机在线视频 | 久久精品一日日躁夜夜躁 | 欧美理论在线观看 | 99精品久久久久久久婷婷 | 日本国产一区 | 小sao货大ji巴cao死你 | 国产在线一区二 | 久久久久麻豆 | 夜色网| 韩国精品久久久 | 久久久久久免费精品 | 91视频色| 91看毛片| 最新中文字幕第一页 | 国产无套视频 | 成年人晚上看的视频 | 99视频在线 | 亚洲视频1区 | 亚洲熟妇av乱码在线观看 | 娇妻高潮浓精白浆xxⅹ | 亚欧成人在线 | 日韩精品系列 | 强伦轩人妻一区二区电影 | 性高潮久久久久 | av免费网址在线观看 | 国产ts在线| 妻色成人网| 色久月 | 香蕉成视频人app下载安装 | 大陆日韩欧美 | 日本公妇乱偷中文字幕 | 一区三区视频 | 无码粉嫩虎白一线天在线观看 | 日本在线视频一区二区三区 | 成人在线不卡 | 国产精品久久久久久无人区 | 中文字幕一区2区3区 | 国产婷婷综合 | 欧美精品在欧美一区二区 | 欧美成人久久久免费播放 | 日本a视频 | 超碰精品在线 | www.youjizz日本| 欧美日韩在线观看一区 | 久久r这里只有精品 | 99热在线免费| 韩日一区二区三区 | 淫片aaa| 日韩精品国产精品 | 免费国产羞羞网站视频 | jizzjizzjizz国产 | 成人久久影院 | 久久精品播放 | 麻豆久久久久久 | 美女屁股无遮挡 |