A. Spring cache

There are many different frameworks available for caching, such as Reids, Caffeine, Ehcache, etc., each with its own advantages. To avoid this, Spring Cache leverages AOP, implements annotation-based caching, and abstracts properly so that business code doesn’t have to worry about what caching framework is used underneath.

2. Coding

1. The maven dependencies

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
</dependencies>
Copy the code

2. Application. yml configuration file

spring:
  redis:
    lettuce:
      pool:
        max-active: 8 # Maximum number of connections in the pool
        max-idle: 8 # Maximum number of free connections in the connection pool
        min-idle: 0 Minimum number of free connections in the connection pool
        max-wait: -1ms A negative value indicates that there is no limit
    host: localhost
    port: 6379
Copy the code

3. Configure the CacheConfig class

/ * * *@Description: Cache configuration *@Author: songrenwei
 * @Date: 2020/12/11/00:00 * /
@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        RedisSerializer<String> stringRedisSerializer = new StringRedisSerializer();
        //default Information cache configuration
        RedisCacheConfiguration default1h = RedisCacheConfiguration.defaultCacheConfig()
                        // Set the expiration time
                        .entryTtl(Duration.ofHours(1))
                        // Serialize the key as String
                        .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer))
                        // Jackson serializes value
                        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jsonSerializer()))
                        // Null values are not cached
                        .disableCachingNullValues()
                        // Set the cache name prefix
                        .prefixCacheNameWith("default_1h:");
        RedisCacheConfiguration m30 = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(30)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer)).serializeValuesW ith(RedisSerializationContext.SerializationPair.fromSerializer(jsonSerializer())).disableCachingNullValues().prefixCache NameWith("srw_");
        RedisCacheConfiguration d30 = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofDays(30)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer)).serializeValuesW ith(RedisSerializationContext.SerializationPair.fromSerializer(jsonSerializer())).disableCachingNullValues().prefixCache NameWith("srw_");
        RedisCacheConfiguration h24 = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(24)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer)).serializeValuesW ith(RedisSerializationContext.SerializationPair.fromSerializer(jsonSerializer())).disableCachingNullValues().prefixCache NameWith("srw_");
        RedisCacheConfiguration s60 = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(60)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer)).serializeValuesW ith(RedisSerializationContext.SerializationPair.fromSerializer(jsonSerializer())).disableCachingNullValues().prefixCache NameWith("srw_");

        Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new LinkedHashMap<String, RedisCacheConfiguration>(8) {
            private static final long serialVersionUID = 2474073019770319870L;
            {
                put("60s", s60);
                put("30m", m30);
                put("24h", h24);
                put("30d", d30);
                put("default", default1h); }};return new RedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory), default1h, redisCacheConfigurationMap);
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        RedisSerializer<Object> jackson2JsonRedisSerializer = jsonSerializer();
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // Key uses String serialization
        template.setKeySerializer(stringRedisSerializer);
        // The hash key also uses String serialization
        template.setHashKeySerializer(stringRedisSerializer);
        // Value serialization uses Jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // The hash value serialization method uses Jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    private RedisSerializer<Object> jsonSerializer(a) {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);


        // Resolve the query cache conversion exception
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance , ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        returnjackson2JsonRedisSerializer; }}Copy the code

4. Test

4.1 the controller

@Slf4j
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;

    @GetMapping("/query/{id}")
    publicJsonResult<? > query(@PathVariable("id") Long id) {
        returnJsonResult.successResponse(userService.query(id)); }}Copy the code

4.2 the service

@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;

    @Cacheable(value = "30m", key = "#id", unless = "#result == null")
    @Override
    public User query(Long id) {
        returnuserMapper.selectById(id); }}Copy the code

4.3 Test Results

Refresh redis before calling, there is no corresponding key belowPostman calls the interfaceSuccessful response, view logsRefresh the redisIf the key is stored in redis and the cache validity period is set, the interface is adjusted and the log is displayed. If no log is displayed, the redis has been accessed.