Redis實戰-詳細配置-優雅的使用Redis註解/RedisTemplate

1. 簡介

當咱們對redis的基本知識有必定的瞭解後,咱們再經過實戰的角度學習一下在SpringBoot環境下,如何優雅的使用redis。java

咱們經過使用SpringBoot內置的Redis註解(文章最後有解釋)來操做User相關的信息,mysql

再經過Redis工具類的方式操做Role相關信息來全面的學習Redis的使用。web

嫌篇幅太長的 能夠直接跳到2.6查看具體邏輯便可。redis

2. 開擼

2.1 項目結構

結構說明:spring

├── src
│   └── main
│       ├── java
│       │   └── com
│       │       └── ldx
│       │           └── redis
│       │               ├── RedisApplication.java # 啓動類
│       │               ├── config
│       │               │   └── RedisConfig.java # redis 配置類
│       │               ├── constant
│       │               │   └── CacheConstant.java # 緩存key常量類
│       │               ├── controller
│       │               │   ├── RoleController.java # 角色管理控制器
│       │               │   └── UserController.java # 用戶管理控制器
│       │               ├── entity
│       │               │   ├── SysRole.java # 角色entity
│       │               │   └── SysUser.java # 用戶entity
│       │               ├── mapper
│       │               │   ├── SysRoleMapper.java # 角色持久層
│       │               │   └── SysUserMapper.java # 用戶持久層
│       │               ├── service
│       │               │   ├── SysRoleService.java # 角色接口層
│       │               │   ├── SysUserService.java # 用戶接口層
│       │               │   └── impl
│       │               │       ├── SysRoleServiceImpl.java # 角色接口實現層
│       │               │       └── SysUserServiceImpl.java # 用戶接口實現層
│       │               └── util
│       │                   └── RedisUtil.java # redis 工具類
│       └── resources
│           └── application.yaml # 系統配置文件
└── pom.xml # 依賴管理

2.2 導入依賴

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.5.3</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.ldx</groupId>
   <artifactId>redis</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>redis</name>
   <description>Demo project for Spring Boot</description>
   <properties>
      <java.version>1.8</java.version>
   </properties>
   <dependencies>
      <!--spring-web-->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <!-- redis -->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-redis</artifactId>
      </dependency>
      <!-- lettuce pool -->
      <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-pool2</artifactId>
      </dependency>
      <!-- mybatis-plus -->
      <dependency>
         <groupId>com.baomidou</groupId>
         <artifactId>mybatis-plus-boot-starter</artifactId>
         <version>3.4.2</version>
      </dependency>
      <!-- mysql驅動 -->
      <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
      </dependency>
      <!-- lombok 工具包 -->
      <dependency>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
         <optional>true</optional>
      </dependency>
   </dependencies>

   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
               <excludes>
                  <exclude>
                     <groupId>org.projectlombok</groupId>
                     <artifactId>lombok</artifactId>
                  </exclude>
               </excludes>
            </configuration>
         </plugin>
      </plugins>
   </build>
</project>

2.3 項目基本配置

2.3.1 application.yaml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: 123456
    type: com.zaxxer.hikari.HikariDataSource
  # redis 配置
  redis:
    # 地址
    host: localhost
    # 端口,默認爲6379
    port: 6379
    # 密碼
    password:
    # 鏈接超時時間
    timeout: 10s
    lettuce:
      pool:
        # 鏈接池中的最小空閒鏈接
        min-idle: 0
        # 鏈接池中的最大空閒鏈接
        max-idle: 8
        # 鏈接池的最大數據庫鏈接數
        max-active: 8
        # #鏈接池最大阻塞等待時間(使用負值表示沒有限制)
        max-wait: -1ms

mybatis-plus:
  # 設置Mapper接口所對應的XML文件位置,若是你在Mapper接口中有自定義方法,須要進行該配置
  mapper-locations: classpath*:mapper/*.xml
  # 設置別名包掃描路徑,經過該屬性能夠給包中的類註冊別名
  type-aliases-package: com.ldx.redis.entity
  configuration:
    # 控制檯sql打印
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

# 日誌配置
logging:
  level:
    com.ldx.redis.service.impl: debug
    org.springframework: warn

2.3.2 啓動類

@EnableCaching:激活緩存支持sql

@MapperScan: 掃描mapper接口層數據庫

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

/**
 * 啓動類
 * @author ludangxin
 * @date 2021/8/11
 */
@EnableCaching
@MapperScan(basePackages = "com.ldx.redis.mapper")
@SpringBootApplication
public class RedisApplication {
  public static void main(String[] args) {
    SpringApplication.run(RedisApplication.class, args);
  }
}

2.4 redis配置

2.4.1 RedisConfig

咱們除了在application.yaml中加入redis的基本配置外,通常還須要配置redis key和value的序列化方式,以下:apache

註解:json

  1. 其默認的序列化方式爲JdkSerializationRedisSerializer,這種方式跨語言和可讀性都不太好,咱們將其切換爲Jackson2JsonRedisSerializer緩存

  2. 可使用entryTtl()爲對應的模塊設置過時時長。

redisTemplate:參考redisTemplate()

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ldx.redis.constant.CacheConstant;
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.cache.RedisCacheWriter;
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.StringRedisSerializer;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * redis配置類
 * @author ludangxin
 * @date 2021/8/11
 */
@Configuration
public class RedisConfig {
    
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        //設置不一樣cacheName的過時時間
        Map<String, RedisCacheConfiguration> configurations = new HashMap<>(16);
        // 序列化方式
        Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = getJsonRedisSerializer();
        RedisSerializationContext.SerializationPair<Object> serializationPair =
           RedisSerializationContext.SerializationPair.fromSerializer(jsonRedisSerializer);
        // 默認的緩存時間
        Duration defaultTtl = Duration.ofSeconds(20L);
        // 用戶模塊的緩存時間
        Duration userTtl = Duration.ofSeconds(50L);
        // 默認的緩存配置
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
           //.entryTtl(defaultTtl)
           .serializeValuesWith(serializationPair);
        // 自定義用戶模塊的緩存配置 自定義的配置能夠覆蓋默認配置(當前的模塊)
        configurations.put(CacheConstant.USER_CACHE_NAME, RedisCacheConfiguration.defaultCacheConfig()
           //.entryTtl(userTtl)
           .serializeValuesWith(serializationPair)
        );

        return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory))
           .cacheDefaults(redisCacheConfiguration)
           .withInitialCacheConfigurations(configurations)
           // 事物支持 
           .transactionAware()
           .build();
    }

    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = getJsonRedisSerializer();
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key採用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也採用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式採用jackson
        template.setValueSerializer(jsonRedisSerializer);
        // hash的value序列化方式採用jackson
        template.setHashValueSerializer(jsonRedisSerializer);
        // 支持事物
        //template.setEnableTransactionSupport(true);
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 設置jackson的序列化方式
     */
    private Jackson2JsonRedisSerializer<Object> getJsonRedisSerializer() {
        Jackson2JsonRedisSerializer<Object> redisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        redisSerializer.setObjectMapper(om);
        return redisSerializer;
    }
}

2.4.1 CacheConstant

咱們爲了防止redis中key的重複,儘可能會給不一樣的數據主體加上不一樣的前綴,這樣咱們在查看和統計的時候也方便操做。

/**
 * 緩存key 常量類
 * @author ludangxin
 * @date 2021/8/11
 */
public interface CacheConstant {
   /**
    * 用戶cache name
    */
   String USER_CACHE_NAME = "user_cache";

   /**
    * 用戶信息緩存key前綴
    */
   String USER_CACHE_KEY_PREFIX = "user_";

   /**
    * 角色cache name
    */
   String ROLE_CACHE_NAME = "role_cache";

   /**
    * 角色信息緩存key前綴
    */
   String ROLE_CACHE_KEY_PREFIX = "role_";

   /**
    * 獲取角色cache key
    * @param suffix 後綴
    * @return key
    */
   static String getRoleCacheKey(String suffix) {
      return ROLE_CACHE_NAME + "::" + ROLE_CACHE_KEY_PREFIX + suffix;
   }
}

2.4.2 RedisUtil

import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * spring redis 工具類
 * @author ludangxin
 **/
@Component
@RequiredArgsConstructor
@SuppressWarnings(value = { "unchecked", "rawtypes" })
public class RedisUtil {
    public final RedisTemplate redisTemplate;

    /**
     * 緩存基本的對象,Integer、String、實體類等
     * @param key 緩存的鍵值
     * @param value 緩存的值
     * @return 緩存的對象
     */
    public <T> ValueOperations<String, T> setCacheObject(String key, T value) {
        ValueOperations<String, T> operation = redisTemplate.opsForValue();
        operation.set(key, value);
        return operation;
    }

    /**
     * 緩存基本的對象,Integer、String、實體類等
     * @param key 緩存的鍵值
     * @param value 緩存的值
     * @param timeout 時間
     * @param timeUnit 時間顆粒度
     * @return 緩存的對象
     */
    public <T> ValueOperations<String, T> setCacheObject(String key, T value, Integer timeout, TimeUnit timeUnit) {
        ValueOperations<String, T> operation = redisTemplate.opsForValue();
        operation.set(key, value, timeout, timeUnit);
        return operation;
    }

    /**
     * 得到緩存的基本對象。
     * @param key 緩存鍵值
     * @return 緩存鍵值對應的數據
     */
    public <T> T getCacheObject(String key) {
        ValueOperations<String, T> operation = redisTemplate.opsForValue();
        return operation.get(key);
    }

    /**
     * 刪除單個對象
     * @param key
     */
    public void deleteObject(String key) {
        redisTemplate.delete(key);
    }

    /**
     * 刪除集合對象
     * @param collection
     */
    public void deleteObject(Collection collection) {
        redisTemplate.delete(collection);
    }

    /**
     * 緩存List數據
     * @param key 緩存的鍵值
     * @param dataList 待緩存的List數據
     * @return 緩存的對象
     */
    public <T> ListOperations<String, T> setCacheList(String key, List<T> dataList) {
        ListOperations listOperation = redisTemplate.opsForList();
        if (null != dataList) {
            int size = dataList.size();
            for (int i = 0; i < size; i++) {
                listOperation.leftPush(key, dataList.get(i));
            }
        }
        return listOperation;
    }

    /**
     * 得到緩存的list對象
     * @param key 緩存的鍵值
     * @return 緩存鍵值對應的數據
     */
    public <T> List<T> getCacheList(String key) {
        List<T> dataList = new ArrayList<T>();
        ListOperations<String, T> listOperation = redisTemplate.opsForList();
        Long size = listOperation.size(key);
        for (int i = 0; i < size; i++) {
            dataList.add(listOperation.index(key, i));
        }
        return dataList;
    }

    /**
     * 緩存Set
     * @param key 緩存鍵值
     * @param dataSet 緩存的數據
     * @return 緩存數據的對象
     */
    public <T> BoundSetOperations<String, T> setCacheSet(String key, Set<T> dataSet) {
        BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
        Iterator<T> it = dataSet.iterator();
        while (it.hasNext()) {
            setOperation.add(it.next());
        }
        return setOperation;
    }

    /**
     * 得到緩存的set
     * @param key
     * @return
     */
    public <T> Set<T> getCacheSet(String key) {
        Set<T> dataSet = new HashSet<T>();
        BoundSetOperations<String, T> operation = redisTemplate.boundSetOps(key);
        dataSet = operation.members();
        return dataSet;
    }

    /**
     * 緩存Map
     * @param key
     * @param dataMap
     * @return
     */
    public <T> HashOperations<String, String, T> setCacheMap(String key, Map<String, T> dataMap) {
        HashOperations hashOperations = redisTemplate.opsForHash();
        if (null != dataMap) {
            for (Map.Entry<String, T> entry : dataMap.entrySet()) {
                hashOperations.put(key, entry.getKey(), entry.getValue());
            }
        }
        return hashOperations;
    }

    /**
     * 得到緩存的Map
     * @param key
     * @return
     */
    public <T> Map<String, T> getCacheMap(String key) {
        Map<String, T> map = redisTemplate.opsForHash().entries(key);
        return map;
    }

    /**
     * 得到緩存的基本對象列表
     * @param pattern 字符串前綴
     * @return 對象列表
     */
    public Collection<String> keys(String pattern) {
        return redisTemplate.keys(pattern);
    }
}

2.5 controller

2.5.1 UserController

import com.ldx.redis.entity.SysUser;
import com.ldx.redis.service.SysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;

/**
 * 用戶管理
 * @author ludangxin
 * @date 2021/8/11
 */
@RestController
@RequestMapping("user")
@RequiredArgsConstructor
public class UserController {
   private final SysUserService userService;

   @GetMapping
   public List<SysUser> queryAll() {
      return userService.queryAll();
   }

   @GetMapping("{userId}")
   public SysUser getUserInfo(@PathVariable Long userId) {
      return userService.getUserInfo(userId);
   }

   @PostMapping
   public String add(@RequestBody SysUser user) {
      userService.add(user);
      return "新增成功~";
   }

   @PutMapping("{userId}")
   public String update(@PathVariable Long userId, @RequestBody SysUser user) {
      userService.update(userId, user);
      return "更新成功~";
   }

   @DeleteMapping("{userId}")
   public String del(@PathVariable Long userId) {
      userService.delete(userId);
      return "刪除成功~";
   }
}

2.5.2 RoleController

import com.ldx.redis.entity.SysRole;
import com.ldx.redis.service.SysRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;

/**
 * 角色管理
 * @author ludangxin
 * @date 2021/8/12
 */
@RestController
@RequestMapping("role")
@RequiredArgsConstructor
public class RoleController {
   private final SysRoleService roleService;

   @GetMapping
   public List<SysRole> queryAll() {
      return roleService.queryAll();
   }

   @GetMapping("{roleId}")
   public SysRole getUserInfo(@PathVariable Long roleId) {
      return roleService.getRoleInfo(roleId);
   }

   @PostMapping
   public String add(@RequestBody SysRole role) {
      roleService.add(role);
      return "新增成功~";
   }

   @PutMapping("{roleId}")
   public String update(@PathVariable Long roleId, @RequestBody SysRole role) {
      roleService.update(roleId, role);
      return "更新成功~";
   }

   @DeleteMapping("{roleId}")
   public String del(@PathVariable Long roleId) {
      roleService.delete(roleId);
      return "刪除成功~";
   }
}

2.6 service.impl

2.6.1 UserServiceImpl

優雅的使用redis註解實現對數據的緩存

@Cacheable:unless:當unless成立時則不緩存。這裏判斷size主要是不想將空值存入redis。

CacheConstant.USER_CACHE_KEY_PREFIX + "' + #userId":其key = 指定前綴 + 當前方法實參(userId)。

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ldx.redis.constant.CacheConstant;
import com.ldx.redis.entity.SysUser;
import com.ldx.redis.mapper.SysUserMapper;
import com.ldx.redis.service.SysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import java.util.List;

/**
 * 用戶管理實現
 * @author ludangxin
 * @date 2021/8/11
 */
@Slf4j
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = CacheConstant.USER_CACHE_NAME)
public class SysUserServiceImpl implements SysUserService {
   private final SysUserMapper userMapper;

   @Override
   @Cacheable(key = "'" + CacheConstant.USER_CACHE_KEY_PREFIX + "all'", unless = "#result.size() == 0")
   public List<SysUser> queryAll() {
      log.debug("查詢所有用戶信息~");
      LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
      return userMapper.selectList(queryWrapper);
   }

   
   @Override
   @Cacheable(key = "'" + CacheConstant.USER_CACHE_KEY_PREFIX + "' + #userId", unless = "#result == null")
   public SysUser getUserInfo(Long userId) {
      log.debug("查詢用戶:{} 詳情", userId);
      return userMapper.selectById(userId);
   }

   @Override
   @CacheEvict(key = "'" + CacheConstant.USER_CACHE_KEY_PREFIX + "all'")
   public void add(SysUser user) {
      log.debug("新增用戶:{}", user.getNickName());
      userMapper.insert(user);
   }

   @Override
   @Caching(evict = {@CacheEvict(key = "'" + CacheConstant.USER_CACHE_KEY_PREFIX + "all'"),
                     @CacheEvict(key = "'" + CacheConstant.USER_CACHE_KEY_PREFIX + "' + #userId")
   })
   public void update(Long userId, SysUser user) {
      log.debug("更新用戶:{}", user.getNickName());
      user.setId(userId);
      userMapper.updateById(user);
   }

   @Override
   @Caching(evict = {@CacheEvict(key = "'" + CacheConstant.USER_CACHE_KEY_PREFIX + "all'"),
                     @CacheEvict(key = "'" + CacheConstant.USER_CACHE_KEY_PREFIX + "' + #userId")
   })
   public void delete(Long userId) {
      log.debug("刪除用戶:{}", userId);
      userMapper.deleteById(userId);
   }
}

2.6.2 SysRoleServiceImpl

使用redis工具類實現對數據的緩存。

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ldx.redis.constant.CacheConstant;
import com.ldx.redis.entity.SysRole;
import com.ldx.redis.mapper.SysRoleMapper;
import com.ldx.redis.service.SysRoleService;
import com.ldx.redis.util.RedisUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * 角色管理
 * @author ludangxin
 * @date 2021/8/11
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysRoleServiceImpl implements SysRoleService {
   private final SysRoleMapper roleMapper;

   private final RedisUtil redisUtil;

   String allKey = CacheConstant.getRoleCacheKey("all");

   @Override
   public List<SysRole> queryAll() {
      List<SysRole> roles = redisUtil.getCacheList(allKey);
      if(!CollectionUtils.isEmpty(roles)) {
         return roles;
      }
      log.debug("查詢所有角色信息~");
      LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
      List<SysRole> sysRoles = roleMapper.selectList(queryWrapper);
      if(CollectionUtils.isEmpty(sysRoles)) {
         return Collections.emptyList();
      }
      redisUtil.setCacheList(allKey, sysRoles);
      return sysRoles;
   }

   @Override
   public SysRole getRoleInfo(Long roleId) {
      String roleCacheKey = CacheConstant.getRoleCacheKey(String.valueOf(roleId));
      SysRole role = redisUtil.getCacheObject(roleCacheKey);

      if(Objects.nonNull(role)) {
         return role;
      }
      log.debug("查詢角色:{} 詳情", roleId);
      SysRole sysRole = roleMapper.selectById(roleId);

      if(Objects.isNull(sysRole)) {
         return null;
      }
      redisUtil.setCacheObject(roleCacheKey, sysRole);
      return sysRole;
   }

   @Override
   public void add(SysRole role) {
      log.debug("新增角色:{}", role.getName());
      roleMapper.insert(role);
      redisUtil.deleteObject(allKey);
   }

   @Override
   public void update(Long roleId, SysRole role) {
      log.debug("更新角色:{}", role.getName());
      String roleCacheKey = CacheConstant.getRoleCacheKey(String.valueOf(roleId));
      role.setId(roleId);
      roleMapper.updateById(role);
      // 更新緩存
      redisUtil.setCacheObject(roleCacheKey,role);
      // 清除緩存
      redisUtil.deleteObject(allKey);
   }

   @Override
   public void delete(Long roleId) {
      log.debug("刪除角色:{}", roleId);
      roleMapper.deleteById(roleId);
      // 清除緩存
      redisUtil.deleteObject(CacheConstant.getRoleCacheKey(String.valueOf(roleId)));
      redisUtil.deleteObject(allKey);

   }
}

2.7 啓動測試

這裏只測試了user模塊(都測試而且貼圖會顯得篇幅太長且繁瑣),role模塊本人測試後結果正確。

查詢列表:

​ 調用接口返回所有數據並緩存完成,再次調用無查詢日誌輸出,符合預期。

​ 接口調用:

​ 查看緩存:

查看用戶詳情:

​ 接口調用返回用戶詳情信息並緩存完成,再次調用無查詢日誌輸出,符合預期。

​ 接口調用:

​ 查看緩存:

更新數據:

​ 接口調用返回更新成功,而且查看所有的緩存被清除。符合預期。

​ 接口調用:

​ 查看緩存:

3. 內置緩存註解

3.1 @CacheConfig

@Cacheable()裏面都有一個value=「xxx」的屬性,這顯然若是方法多了,寫起來也是挺累的,若是能夠一次性聲明完 那就省事了, 因此,有了@CacheConfig這個配置,@CacheConfig is a class-level annotation that allows to share the cache names,若是你在你的方法寫別的名字,那麼依然以方法的名字爲準。

3.2 @Cacheable

@Cacheable(value="myCache"),這個註釋的意思是,當調用這個方法的時候,會從一個名叫myCache 的緩存中查詢,若是沒有,則執行實際的方法(即查詢數據庫),並將執行的結果存入緩存中,不然返回緩存中的對象。

3.3 @CachePut

@CachePut 的做用 主要針對方法配置,可以根據方法的請求參數對其結果進行緩存,和 @Cacheable 不一樣的是,它每次都會觸發真實方法的調用。

3.4 @CacheEvict

@CachEvict 的做用 主要針對方法配置,可以根據必定的條件對緩存進行清空。

// 清空當前cache name下的全部key
@CachEvict(allEntries = true)

3.5 @Caching

@Caching可使註解組合使用,好比根據id查詢用戶信息,查詢完的結果爲{key = id,value = userInfo},但咱們如今爲了方遍,想用用戶的手機號,郵箱等緩存對應用戶的信息,這時候咱們就要使用@Caching。例:

@Caching(put = {
@CachePut(value = "user", key = "#user.id"),
@CachePut(value = "user", key = "#user.username"),
@CachePut(value = "user", key = "#user.email")
})
public User getUserInfo(User user){
    ...
return user;
}
相關文章
相關標籤/搜索