2 Springboot中使用redis,配置redis的key value生成策略
上一篇裡講過了redis在spring boot中的簡單使用,對於單個物件的增刪改查的預設操作。
下面來看一下在redis中,這些快取的資料是如何儲存的,為了便於後面的快取的key的可讀性,先修改一下cache的key。
給key上加個字串postId,用類似於postId3作為key,整個Post物件作為value。呼叫controller的save介面新增一條Post資料,開啟redis視覺化管理器,檢視一下儲存的這條資料:@CacheConfig(cacheNames = "post") public interface PostRepository extends PagingAndSortingRepository<Post, Integer> { @Cacheable(key = "'PostId' + #p0") Post findById(int id); /** * 新增或修改時 */ @CachePut(key = "'PostId' + #p0.id") @Override Post save(Post post); @Transactional @Modifying @CacheEvict(key = "'PostId' + #p0") int deleteById(int id); }
發現key是以post:XX開頭的亂碼形式。這是預設的key生成策略,是通過序列化Serializable後生成的key,當讀取快取時系統再通過反序列化得到Post物件。
如果我們想修改序列化方式,來生成一個可讀的key和value,下面是方法。
譬如如果key我想用字串如 PostId1,value為Post物件轉成的Json物件:
上面這個類主要是定製RedisTemplate的KeySerializer和ValueSerializer。其中StringRedisSerializer和Jackson2JsonRedisSerializer都是系統提供的已實現的序列化方式。package com.tianyalei.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.cache.CacheManager; 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.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; /** * Created by wuwf on 17/4/24. */ @Configuration public class RedisCacheConfig { @Bean public CacheManager cacheManager(RedisTemplate<?,?> redisTemplate) { CacheManager cacheManager = new RedisCacheManager(redisTemplate); return cacheManager; } @Bean public RedisTemplate<String, String> getRedisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, String> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(factory); //key序列化方式,但是如果方法上有Long等非String型別的話,會報型別轉換錯誤 //所以在沒有自己定義key生成策略的時候,以下這個程式碼建議不要這麼寫,可以不配置或者自己實現ObjectRedisSerializer RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long型別不可以會出現異常資訊; redisTemplate.setKeySerializer(redisSerializer); // redisTemplate.setHashKeySerializer(redisSerializer); // redisTemplate.setValueSerializer(redisSerializer); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } }
StringXX是轉為String,JacksonXX是將物件轉為json。需要注意這裡Key使用了StringRedisSerializer,那麼Key只能是String型別的,不能為Long,Integer,否則會報錯拋異常。就是假如PostRepository裡定義的@Cacheable(key="#p0")的話就會報錯,因為這樣作為key的是int型,key必須為String。
上面的方法就是設定了key和value的序列化方式,然後返回預設的RedisTemplate。RedisTemplate有幾個預設的實現類,常用的如StringRedisTemplate就是提供的RedisTemplate<String, String>的實現。可以參考下面的文章簡單瞭解下StringRedisTemplate。
http://blog.didispace.com/springbootredis/和http://blog.csdn.net/fengzheku/article/details/49735785
StringRedisTemplate其實就是使用StringRedisSerializer對key,value設定序列化。
當然也可以自己定義序列化方式,使用別的Json工具類,或者別的什麼方法來完成序列化方式。
完成RedisTemplate的設定後,再次save一個Post物件來看看在redis裡的儲存方式。
可以看到PostId12就是剛新增成功物件,key為PostId12,即是PostResposity裡配置的key,value為Json字串和一個類名。
然後還多了一個post~keys的zset物件,裡面存放的是key。
通過上面的配置,我們就完成對序列化方式自定義的配置,尤其是key的定製,能方便日後的檢視以及在別的地方操作key時更易識別。
在上一篇裡,還提到了無需配置yml中redis的屬性,ip、port之類的,系統會識別預設的。下面來看看如何使用自己的redis配置。
修改yml檔案:
spring:
jpa:
database: mysql
show-sql: true
hibernate:
ddl-auto: update
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/tx2
username: root
password:
redis:
host: localhost
port: 6379
password:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: 10000
這裡面加入了redis 的配置。可以用ctrl加左鍵點選host或者post屬性,進入類。
這個就是採用prefix=spring.redis字首的配置類,我們也可以自定義類似的配置類。
在配置檔案裡設定了ip和port及pool等屬性,然後開啟RedisCacheConfig類,來使用yml裡的這些redis配置。
package com.tianyalei.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
/**
* Created by wuwf on 17/4/24.
*/
@Configuration
public class RedisCacheConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.pool.min-idle}")
private int minIdle;
@Value("${spring.redis.pool.max-wait}")
private int maxWait;
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setPassword(password);
factory.setHostName(host);
factory.setPort(port);
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(maxActive);
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMinIdle(minIdle);
jedisPoolConfig.setMaxWaitMillis(maxWait);
factory.setPoolConfig(jedisPoolConfig);
return factory;
}
@Bean
public RedisTemplate<String, String> getRedisTemplate() {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(jedisConnectionFactory());
//key序列化方式,但是如果方法上有Long等非String型別的話,會報型別轉換錯誤
RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long型別不可以會出現異常資訊;
redisTemplate.setKeySerializer(redisSerializer);
// redisTemplate.setHashKeySerializer(redisSerializer);
// redisTemplate.setValueSerializer(redisSerializer);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
配置檔案裡的內容主要目的就是為了配置JedisConnectionFactory,這裡我們使用配置檔案定義的屬性來建立一個自己的JedisConnectionFactory。然後在建立RedisTemplate時使用這個自定義的JedisConnectionFactory即可。
這樣就完成了redis的自定義資訊,以後就可以使用RedisTemplate來操作redis了。可以通過修改yml裡的連線資訊來看看是否已生效。
如果覺得上面使用自定義配置的步驟複雜,可以使用簡單方式,如下
@Bean
public RedisTemplate<String, String> getRedisTemplate(JedisConnectionFactory jedisConnectionFactory) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(jedisConnectionFactory);
//key序列化方式,但是如果方法上有Long等非String型別的話,會報型別轉換錯誤
RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long型別不可以會出現異常資訊;
redisTemplate.setKeySerializer(redisSerializer);
// redisTemplate.setHashKeySerializer(redisSerializer);
// redisTemplate.setValueSerializer(redisSerializer);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
該類只保留這一個方法就可以了,方法里加上引數JedisConnectionFactory,然後直接使用就行。上面定義的那些配置會被框架自動解釋到這個引數裡。效果和自己手工建立JedisConnectionFactory並設定引數是一樣的。
該篇到此為止,下面還有幾個問題需要考慮:
1.怎麼處理db操作成功了,但操作redis失敗。譬如剛才修改一下yml的ip地址,讓redis連線不上,那麼對db的操作還是會成功,但redis資料就不對了。
2.怎麼操作集合資料,因為一個key對應一個集合轉化的json字串,是無法單獨新增一條物件資料的,只能全失效或全成功,這樣的話就不適合儲存頻繁改變的集合資料。
下篇來看看這些問題。
相關推薦
2 Springboot中使用redis,配置redis的key value生成策略
上一篇裡講過了redis在spring boot中的簡單使用,對於單個物件的增刪改查的預設操作。 下面來看一下在redis中,這些快取的資料是如何儲存的,為了便於後面的快取的key的可讀性,先修改一下cache的key。 @CacheConfig(cacheNames =
Springboot 中 Redis快取使用 @Cacheable不生效的原因,以及@Cacheable 的一些注意點
Springboot 中 Redis快取使用 @Cacheable不生效的原因,以及@Cacheable 的一些注意點 1、有如下程式碼 // get 方法呼叫了 stockGive 方法,stockGive 方法使用了快取 // 但是每次執行get 方
SpringBoot中多資料來源 配置mybatis 駝峰命名不管用,帶下劃線欄位返回null值
在springboot中 開啟是自動轉換,但是,這個配置根本沒有生效, 當查出來的資料時,只要欄位名中有 下劃線的欄位, 就會出現 null 在者我的工程是多資料來源工程,這是導致這個配置沒有生效的原因,因為他不知道為哪個資料來源開啟駝峰命名 所以我們需要在配置多資料來源的檔案
SpringBoot 中的aop配置,完成日誌記錄功能
第一步:在pom.xml下新增依賴 因為springboot已經新增過日誌記錄功能的依賴 <!-- 核心模組,包括自動配置支援、日誌支援 --> <dependency> <groupId>org.s
關於修改springboot中redis配置中的修改RedisTemplate 預設的序列化規則(修改成JSON資料型別)
原理:覆蓋預設配置類; 在建立的springboot專案中的啟動類中: public static void main(String[] args) { SpringApplication.run(TestspringBoot0
SpringBoot中的常用配置
comm highlight tar -type cati pid 添加 maven項目 http請求 一 . 關於在application.properties文件中的一些常見配置 1.server.port=8888 :表示配置端口 2.server
Springboot 中類不能使用@Value註解從yml中載入值
對於下面的類,使用了@Value,但是不能從yml中讀取值,怎麼辦? 帶有@Value標籤類: package com.itmuch.cloud; import org.springframework.beans.factory.annotation.Value; import org
springboot中generator相關配置檔案
generator.properties # jdbc jdbc.driverClass = com.mysql.jdbc.Driver jdbc.url = jdbc:mysql://localhost:3306/test?autoReconnect=true&useUnicode=
Redis詳解 - SpringBoot整合Redis,RedisTemplate和註解兩種方式的使用
本文主要講 Redis 的使用,如何與 SpringBoot 專案整合,如何使用註解方式和 RedisTemplate 方式實現快取。最後會給一個用 Redis 實現分散式鎖,用在秒殺系統中的案例。 更多 Redis 的實際運用場景請關注開源專案 coderiver 專案地址:github.com/cac
springboot整合redis,實現session共享
一直對serssion的共享有著很大的疑惑,對於我現在的工作的地方,所在的部門,因為沒有前臺頁面,純屬後臺。所以,不會存在session的共享問題。但是出於好奇,也是心裡的疑惑,今天也動手實驗了下。
如何解讀springboot 中約定大於配置、JPA是什麼、咋用
1、大家都知道springboot 的核心:約定大於配置,什麼意思呢? 那麼怎麼每個約定大於配置呢?摘自百科一段: 》在微服務體系中,簡單說,在springboot 中,約定大於配置這句話可以從以下來理解: 1、開發人員僅需規定應用中不符約定的部分; 2、在沒有規定配置
tp5中redis快取配置及使用
首先看手冊https://www.kancloud.cn/manual/thinkphp5/118131 1.修改config.php的配置檔案 'cache' => [ // 驅動方式 'type' => 'redis',
springboot中bean形式配置mybatis的分頁外掛
mybatis的分頁外掛在開發中往往必不可少,使用起來也非常簡單。以往我們的配置都是在xml中進行的,springboot推薦使用bean的形式進行配置。所以,今天就來看看使用java bean的形式配置mybatis的分頁外掛。 1、新增依賴 首先引入必要的依賴:分頁外掛的依賴 <
springboot中redis使用list來快取資料
[@[email protected]]Let bygones be bygones*Love today! 一、應用背景 最近有個專案有這樣的背景:從mq訂閱了一批資料,收到資料後會將資料按
SpringBoot中靜態資源配置
在Springboot中預設的靜態資源路徑有:classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,從這裡可以看出這裡的靜態資源路徑都是在classpath
阿里雲伺服器使用yum安裝redis,配置開機自啟
前言 自己買了個阿里雲伺服器,在安裝redis之後,想要將redis註冊為系統服務,並設定開機自啟,走了些彎路,但最終弄好,記錄下,也希望能幫到廣大碼農。 1.安裝gcc 如果沒有需要先進行安裝,使用一下命令,但一般阿里雲伺服器都會有 yum install cpp
SpringBoot中redis的使用介紹
REmote DIctionary Server(Redis) 是一個由Salvatore Sanfilippo寫的key-value儲存系統。 Redis是一個開源的使用ANSI C語言編寫、遵守BSD協議、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。 它通常
springboot之redis的配置
當看這邊文章之前,相信大家對redis已經能夠熟悉的運用,對springmvc也有一定的瞭解了。redis,在個人的觀點中是一個很優秀的快取組建,無論是單用,還是做叢集用,輕便,簡單,持久,都很不錯。言歸正傳,看下錶題,這裡講一下springboot配置redis是如何實現
SpringBoot中AOP的配置
AOP目的: 面向切面程式設計(aspect-oriented programming,AOP)主要實現的目的是針對業務處理過程中的切面進行提取,諸如日誌、事務管理和安全這樣的系統服務,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發
SpringBoot整合Redis,以及MybatisPlus分頁、Mapper的使用(一)
概述 這段時間接觸很多知識,也逐漸深入到專案整個流程開發,對Linux也有逐步地認識。雖然有去探索,但感覺能力還不足以寫出來跟大家分享。撰寫本文是瞭解到有些讀者反饋,對於MP(MybatisPlus縮寫)不太瞭解以及如何去使用,但更多還是筆者用完覺得非常強大,