1. 程式人生 > >2 Springboot中使用redis,配置redis的key value生成策略

2 Springboot中使用redis,配置redis的key value生成策略

上一篇裡講過了redis在spring boot中的簡單使用,對於單個物件的增刪改查的預設操作。

下面來看一下在redis中,這些快取的資料是如何儲存的,為了便於後面的快取的key的可讀性,先修改一下cache的key。

@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上加個字串postId,用類似於postId3作為key,整個Post物件作為value。呼叫controller的save介面新增一條Post資料,開啟redis視覺化管理器,檢視一下儲存的這條資料:

發現key是以post:XX開頭的亂碼形式。這是預設的key生成策略,是通過序列化Serializable後生成的key,當讀取快取時系統再通過反序列化得到Post物件。

如果我們想修改序列化方式,來生成一個可讀的key和value,下面是方法。

譬如如果key我想用字串如 PostId1,value為Post物件轉成的Json物件:

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;
    }

}
上面這個類主要是定製RedisTemplate的KeySerializer和ValueSerializer。其中StringRedisSerializer和Jackson2JsonRedisSerializer都是系統提供的已實現的序列化方式。

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

關於修改springbootredis配置的修改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

springbootgenerator相關配置檔案

generator.properties # jdbc jdbc.driverClass = com.mysql.jdbc.Driver jdbc.url = jdbc:mysql://localhost:3306/test?autoReconnect=true&useUnicode=

Redis詳解 - SpringBoot整合RedisRedisTemplate和註解兩種方式的使用

本文主要講 Redis 的使用,如何與 SpringBoot 專案整合,如何使用註解方式和 RedisTemplate 方式實現快取。最後會給一個用 Redis 實現分散式鎖,用在秒殺系統中的案例。 更多 Redis 的實際運用場景請關注開源專案 coderiver 專案地址:github.com/cac

springboot整合redis實現session共享

   一直對serssion的共享有著很大的疑惑,對於我現在的工作的地方,所在的部門,因為沒有前臺頁面,純屬後臺。所以,不會存在session的共享問題。但是出於好奇,也是心裡的疑惑,今天也動手實驗了下。      

如何解讀springboot 約定大於配置、JPA是什麼、咋用

1、大家都知道springboot 的核心:約定大於配置,什麼意思呢? 那麼怎麼每個約定大於配置呢?摘自百科一段: 》在微服務體系中,簡單說,在springboot 中,約定大於配置這句話可以從以下來理解: 1、開發人員僅需規定應用中不符約定的部分; 2、在沒有規定配置

tp5redis快取配置及使用

首先看手冊https://www.kancloud.cn/manual/thinkphp5/118131 1.修改config.php的配置檔案 'cache' => [ // 驅動方式 'type' => 'redis',

springbootbean形式配置mybatis的分頁外掛

mybatis的分頁外掛在開發中往往必不可少,使用起來也非常簡單。以往我們的配置都是在xml中進行的,springboot推薦使用bean的形式進行配置。所以,今天就來看看使用java bean的形式配置mybatis的分頁外掛。 1、新增依賴 首先引入必要的依賴:分頁外掛的依賴 <

springbootredis使用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

SpringBootredis的使用介紹

REmote DIctionary Server(Redis) 是一個由Salvatore Sanfilippo寫的key-value儲存系統。 Redis是一個開源的使用ANSI C語言編寫、遵守BSD協議、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。 它通常

springbootredis配置

當看這邊文章之前,相信大家對redis已經能夠熟悉的運用,對springmvc也有一定的瞭解了。redis,在個人的觀點中是一個很優秀的快取組建,無論是單用,還是做叢集用,輕便,簡單,持久,都很不錯。言歸正傳,看下錶題,這裡講一下springboot配置redis是如何實現

SpringBootAOP的配置

AOP目的: 面向切面程式設計(aspect-oriented programming,AOP)主要實現的目的是針對業務處理過程中的切面進行提取,諸如日誌、事務管理和安全這樣的系統服務,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發

SpringBoot整合Redis以及MybatisPlus分頁、Mapper的使用(一)

概述 這段時間接觸很多知識,也逐漸深入到專案整個流程開發,對Linux也有逐步地認識。雖然有去探索,但感覺能力還不足以寫出來跟大家分享。撰寫本文是瞭解到有些讀者反饋,對於MP(MybatisPlus縮寫)不太瞭解以及如何去使用,但更多還是筆者用完覺得非常強大,