龙空技术网

Redis实战-详细配置-优雅地使用Redis注解/RedisTemplate

爱马士团团长 260

前言:

此时咱们对“redis的使用和配置”可能比较注意,你们都想要剖析一些“redis的使用和配置”的相关知识。那么小编同时在网络上汇集了一些对于“redis的使用和配置””的相关文章,希望大家能喜欢,大家快快来学习一下吧!

1. 简介

当我们对redis的基本知识有一定的了解后,我们再通过实战的角度学习一下在SpringBoot环境下,如何优雅的使用redis。

我们通过使用SpringBoot内置的Redis注解(文章最后有解释)来操作User相关的信息,

再通过Redis工具类的方式操作Role相关信息来全面的学习Redis的使用。

嫌篇幅太长的 可以直接跳到2.6查看具体逻辑即可。

2. 开撸2.1 项目结构结构说明:

├── 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="; xmlns:xsi=";   xsi:schemaLocation=" ;>   <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: -1msmybatis-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 :激活缓存支持

@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")@SpringBootApplicationpublic 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的序列化方式,如下:

注解:其默认的序列化方式为 JdkSerializationRedisSerializer ,这种方式跨语言和可读性都不太好,我们将其切换为 Jackson2JsonRedisSerializer可以使用 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 */@Configurationpublic 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 controller2.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")@RequiredArgsConstructorpublic 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")@RequiredArgsConstructorpublic 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.impl2.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@RequiredArgsConstructorpublic 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;}

标签: #redis的使用和配置