Home  >  Article  >  Database  >  How to use @Cacheable in the integration of springboot and redis

How to use @Cacheable in the integration of springboot and redis

王林
王林forward
2023-05-28 20:59:121448browse

First we need to configure a cache manager, and then we can use cache annotations to manage the cache.

package com.cherish.servicebase.handler;

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.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.cache.RedisCacheConfiguration;
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.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        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);
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        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);
        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration
                .defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();

        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
             // 可以给每个cacheName不同的RedisCacheConfiguration  设置不同的过期时间
            //.withCacheConfiguration("Users",config.entryTtl(Duration.ofSeconds(100)))
                .transactionAware()
                .build();
        return cacheManager;
    }
}

1. @Cacheable

is marked on a method or class to identify that the method or class supports it. cache. After Spring calls the annotation identification method, the return value will be cached in redis to ensure that the next time the method is called with the same conditions, the return value will be obtained directly from the cache. In this way, there is no need to re-execute the business processing process of this method, which improves efficiency.

@Cacheable The three commonly used parameters are as follows:

cacheNames Cache name
key The cached key, you need to pay attention to how the key is written
condition The condition for cache execution, when true is returned Execution

Example

    //查询所有用户,缓存到redis中
    @GetMapping("/selectFromRedis")
    @Cacheable(cacheNames = "Users",key = "&#39;user&#39;")
    public ResultData getUserRedis(){
        List<User> list = userService.list(null);
        return ResultData.ok().data("User",list);
    }

How to use @Cacheable in the integration of springboot and redis

The first query is queried from the database and then cached into redis. Use the redis visualization tool to view the cached information

How to use @Cacheable in the integration of springboot and redis

The second query goes to the cache console and there is no output, so the redis cache is to get the results in redis and return them directly.

How to use @Cacheable in the integration of springboot and redis

@CacheEvict

is marked on the method. After the method is executed, the corresponding cache will be deleted based on the condition or key. Commonly used attributes:

  • allEntries boolean type, indicating whether all elements in the cache need to be cleared

  • key The key of the cache that needs to be deleted

 //调用这个接口结束后,删除指定的Redis缓存
    @PostMapping("updateUser")
    @CacheEvict(cacheNames ="Users",key = "&#39;user&#39;")
    public ResultData updateUser(@RequestBody User user){
        String id = user.getId();
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        wrapper.eq("id",id);
        boolean b = userService.update(user, wrapper);
        return ResultData.ok().data("flag",b);
    }
 //不删除redis缓存
    @PostMapping("updateUser2")
    public ResultData updateUser2(@RequestBody User user){
        String id = user.getId();
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        wrapper.eq("id",id);
        boolean b = userService.update(user, wrapper);
        return ResultData.ok().data("flag",b);
    }

When we update the data in the database, we need to clear the redis cache. Otherwise, the data we query is the data in the redis cache, which will cause inconsistency between the database and cached data.

Example: Call the interface without @CacheEvict annotation to modify the data. The data obtained in the query is before modification.

How to use @Cacheable in the integration of springboot and redis

So when we call the interface to modify the data, we need to clear the cache

Add the @CacheEvict annotation to clear the corresponding cache. At this time, the data is discovered during the query. It is the latest and consistent with the database.

How to use @Cacheable in the integration of springboot and redis

Expiration time

We have implemented the basic functions of Spring Cache and integrated Redis as RedisCacheManger, but as we all know, we are When using the @Cacheable annotation, you cannot give the cache an expiration time. But sometimes in some scenarios we really need to give the cache an expiration time! This is the default expiration time

How to use @Cacheable in the integration of springboot and redis

Data validity period

How to use @Cacheable in the integration of springboot and redis

Custom expiration time

How to use @Cacheable in the integration of springboot and redis

Use the new redis configuration and query the cached data again to see the data validity period

How to use @Cacheable in the integration of springboot and redis

The above is the detailed content of How to use @Cacheable in the integration of springboot and redis. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete