zoukankan      html  css  js  c++  java
  • Redis实战-详细配置-优雅的使用Redis注解/RedisTemplate

    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="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:激活缓存支持

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

    注解:

    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;
    }
    
  • 相关阅读:
    random模块
    collections模块
    re模块
    正则表达式
    递归函数,二分查找
    内置函数,匿名函数
    python 中的爬虫· scrapy框架 重要的组件的介绍
    flask 中的常用组件的使用 ,virtualenv组件和 pipreqs组件 和 偏函数
    Django 中自带的 content_type表 , alipay的接口 需要的配置
    restful 和 restframework
  • 原文地址:https://www.cnblogs.com/ludangxin/p/15139522.html
Copyright © 2011-2022 走看看