springboot进阶学习(十八)springboot缓存机制

springboot缓存机制

基本概念

缓存常见注解
  • @EnableCaching:一般作用再项目启动类上面,表示开启缓存,不加这个注解的化缓存不起作用
  • @Cacheable:可用于类或方法上,在目标方法执行前,会根据@Cacheable注解里面的key去缓存中查询看是否有数据,如果有就直接返回缓存中的key对应的value值。
    不再执行目标方法,如果缓存中没有@Cacheable注解里面的key,则执行目标方法,并将方法的返回值作为value,@Cacheable注解里面的key作为key,以键值对的形式存入缓存。
    (主要用于GET方法)
实例
/**
 * 查询用户信息,查询完成后对结果进行缓存,缓存的名称为userList,key是默认值
 * @return
 */
@Cacheable(cacheNames = {"userList"})
public List<SysUser> findAll() {
    log.info("没有使用缓存查询findAll");
    return sysUserList;
}
  • @CachePut:主要用于方法上,在执行完目标方法后,再对结果进行缓存。
实例
/**
 * 更新用户信息,方法执行完毕后再更新缓存信息
 * @param sysUser
 */
@CachePut(value="userList")
public void updateUser(SysUser sysUser){
    sysUserList.remove(0);
    sysUserList.add(sysUser);
}
  • @CacheEvict:主要用于方法上,默认先调用方法,再删除缓存
    • allEntries: 表示是否清除指定命名空间中的所有数据,默认为false
    • beforeInvocation:表示是否在目标方法执行前使此注解生效。默认为false,即目标方法执行完毕后此注解生效。
实例
/**
 * 新增用户信息,新增完后删除指定的缓存”userList“
 * @param sysUser
 */
@CacheEvict(value="userList", allEntries=true)
public void saveUser(SysUser sysUser){
    sysUserList.add(sysUser);
}
  • @Caching:组合注解。针对复杂情况,此注解可以同时使用@Cacheable、@CacheEvict、@CachePut三种注解中的的任何一种或几种
  • @CacheConfig:加载类上,用于设置缓存的共有属性
缓存注解的常用属性
  1. cacheNames/value:指定缓存主键(Cache)的名字
  2. key:缓存数据使用key,支持spEl语法。key的来源可分为三类,分别是默认的、keyGenerator生成的、主动指定的
  3. condition:指定条件满足才缓存,与unless相反。可以使用spEL语法
  4. unless:否定缓存,当满足条件时,结果不被缓存。可以获取到结果(#result)进行判断。支持spEL语法
  5. sync:是否异步模式。在该模式下unless不被支持。default=false

示例

  1. 创建实体类
@Data
public class SysUser {
    private String id;
    private String username;
    private String password;
}
  1. 创建service
@Service
@Slf4j
public class SysUserServiceImpl {

    public static List<SysUser> sysUserList = new ArrayList<>();

    /**
     * 查询用户信息,查询完成后对结果进行缓存,缓存的名称为userList,key是默认值
     * @return
     */
    @Cacheable(cacheNames = {"userList"})
    public List<SysUser> findAll() {
        log.info("没有使用缓存查询findAll");
        return sysUserList;
    }

    /**
     * 新增用户信息,新增完后删除指定的缓存”userList“
     * @param sysUser
     */
    @CacheEvict(value="userList", allEntries=true)
    public void saveUser(SysUser sysUser){
        sysUserList.add(sysUser);
    }

    /**
     * 更新用户信息,方法执行完毕后再更新缓存信息
     * @param sysUser
     */
    @CachePut(value="userList")
    public void updateUser(SysUser sysUser){
        sysUserList.remove(0);
        sysUserList.add(sysUser);
    }
}

再service里面,没有查询数据库,只是用了一个静态userList来保存数据并且进行测试。能说明问题就行。
3. 创建controller

@RestController
@RequestMapping("test")
public class CatchTestController {

    @Autowired
    private SysUserServiceImpl sysUserService;

    @GetMapping("/findAll")
    public Object findAll(){
        return sysUserService.findAll();
    }

    @RequestMapping("/saveUser")
    public Object saveUser(SysUser sysUser){
        sysUserService.saveUser(sysUser);
        return "添加成功";
    }

    @RequestMapping("/updateUser")
    public Object updateUser(SysUser sysUser){
        sysUserService.updateUser(sysUser);
        return "更新成功";
    }
}
  1. 创建启动类
@SpringBootApplication
@EnableCaching //开启缓存功能
public class Springboot2Test18Application extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(Springboot2Test18Application.class, args);
    }
}

在启动类上使用@EnableCaching 开启缓存功能

测试
  • @Cacheable(cacheNames = {"userList"})测试

    • 第一次执行http://localhost:8088/moyundong/test/findAll,控制台打印“没有使用缓存查询findAll”
    • 第二次执行http://localhost:8088/moyundong/test/findAll,控制台什么也没有打印
  • @CacheEvict(value="userList", allEntries=true)测试

    • 执行http://localhost:8088/moyundong/test/saveUser?id=1001&username=test001&password=1111,添加一条数据
    • 第三次执行http://localhost:8088/moyundong/test/findAll,控制台打印“没有使用缓存查询findAll”,并且会查询出来刚才添加的数据。
    • 第四次执行http://localhost:8088/moyundong/test/findAll,控制台什么也没有打印,但同样查询出刚才添加的数据,与第三次执行结果一样,证明这次是从缓存中取得值
  • @CachePut(value="userList")测试

    • 执行http://localhost:8088/moyundong/test/updateUser?id=1004&username=test004&password=1111,更新一条数据
    • 第五次执行http://localhost:8088/moyundong/test/findAll,控制台什么也没有打印,但是刚才更新的数据已经查询出来了。证明缓存数据已经更新了。

redis缓存示例

上面的示例中,我们没有使用任何第三方缓存组件,使用的是springboot自带的缓存。下来我们看下springboot如何使用redis进行缓存。
redis服务器的安装和开启自行解决。

  1. 引入依赖
<!-- Redis -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-pool2</artifactId>
</dependency>
  1. 添加配置
server:
  port: 8088 # 配置端口
  servlet:
      context-path: /moyundong # 配置项目名称
spring:
  #redis 配置
  redis:
    database: 0
    host: 127.0.0.1
    lettuce:
      pool:
        max-active: 8   #最大连接数据库连接数,设 0 为没有限制
        max-idle: 8     #最大等待连接中的数量,设 0 为没有限制
        max-wait: -1ms  #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
        min-idle: 0     #最小等待连接中的数量,设 0 为没有限制
      shutdown-timeout: 100ms
    password: ''
    port: 6379
  1. 创建SysUserServiceRedisImpl
/**
 * @Description 主要用来测试redis的缓存使用情况
 * @Author www.moyundong.com
 * @Date 2020/6/28 13:17
 */
@Service
@Slf4j
public class SysUserServiceRedisImpl {

    public static List<SysUser> sysUserList = new ArrayList<>();

    /**
     * 查询用户信息,查询完成后对结果进行缓存,缓存的名称为userList,key是默认值
     * @return
     */
    @Cacheable(cacheNames = {"userList"}, key = "#keyTest")
    public List<SysUser> findAll(String keyTest) {
        log.info("没有使用缓存查询findAll");
        return sysUserList;
    }

    /**
     * 新增用户信息,新增完后删除指定的缓存”userList“
     * @param sysUser
     */
    @CacheEvict(value="userList", allEntries=true)
    public void saveUser(SysUser sysUser){
        sysUserList.add(sysUser);
    }

    /**
     * 更新用户信息,方法执行完毕后再更新缓存信息
     * @param sysUser
     */
    @CachePut(cacheNames="userList", key = "#keyTest")
    public List<SysUser> updateUser(SysUser sysUser,String keyTest){
        sysUserList.remove(0);
        sysUserList.add(sysUser);
        return sysUserList;
    }
}

  1. 创建RedisCatchTestController
/**
 * @Description 主要用来测试redis的缓存情况
 * @Author www.moyundong.com
 * @Date 2020/6/28 18:17
 */
@RestController
@RequestMapping("testRedis")
public class RedisCatchTestController {

    @Autowired
    private SysUserServiceRedisImpl sysUserServiceRedisImpl;

    @GetMapping("/findAll")
    public Object findAll(){
        return sysUserServiceRedisImpl.findAll("testRedis01");
    }

    @RequestMapping("/saveUser")
    public Object saveUser(SysUser sysUser){
        sysUserServiceRedisImpl.saveUser(sysUser);
        return "添加成功";
    }

    @RequestMapping("/updateUser")
    public Object updateUser(SysUser sysUser){
        sysUserServiceRedisImpl.updateUser(sysUser,"testRedis01");
        return "更新成功";
    }
}

测试
  • @Cacheable(cacheNames = {"userList"})测试

    • 第一次执行http://localhost:8088/moyundong/testRedis/findAll,控制台打印“没有使用缓存查询findAll”
    • 第二次执行http://localhost:8088/moyundong/testRedis/findAll,控制台什么也没有打印
  • @CacheEvict(value="userList", allEntries=true)测试

    • 执行http://localhost:8088/moyundong/testRedis/saveUser?id=1001&username=test001&password=1111,添加一条数据
    • 第三次执行http://localhost:8088/moyundong/testRedis/findAll,控制台打印“没有使用缓存查询findAll”,并且会查询出来刚才添加的数据。
    • 第四次执行http://localhost:8088/moyundong/testRedis/findAll,控制台什么也没有打印,但同样查询出刚才添加的数据,与第三次执行结果一样,证明这次是从缓存中取得值
  • @CachePut(value="userList")测试

    • 执行http://localhost:8088/moyundong/testRedis/updateUser?id=1004&username=test004&password=1111,更新一条数据
    • 第五次执行http://localhost:8088/moyundong/testRedis/findAll,控制台什么也没有打印,但是刚才更新的数据已经查询出来了。证明缓存数据已经更新了。
总结

对比使用redis和不使用redis的servic方法和里面注解的区别

    1. 使用redis的时候,findAll方法加了个参数keyTest,并且把这个参数设置成了缓存的key。updateUser方法也加了个参数keyTest,并且把这个参数设置成了缓存的key
    1. updateUser方法加了返回值,返回的就是userList,也就是要缓存的内容。

修改了上面两处内容,才确保两次同样的测试顺序和测试参数,结果是一样的。这说明springboot自带的缓存和springboot集成redis缓存后,两者的使用还是稍微有些不一样的,在
实际工作中我们应该多注意。

自定义配置redis

配置了上面的步骤,Spring boot 将自动配置 RedisTemplate,在需要操作 redis 的类中注入 redisTemplate; 这样我们就可以通过redisTemplate设置缓存和查询缓存,非常方便。

    1. 自定义缓存工具类
@Component
public class RedisUtil {
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 设置key不超时
     * @param key
     * @return
     */
    public boolean persist(String key){
        try{
            redisTemplate.persist(key);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     * @return
     */
    public boolean expire(String key, long time) {
        try {
            redisTemplate.expire(key, time, TimeUnit.SECONDS);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据key 获取过期时间
     *
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除缓存
     *
     * @param key 可以传一个值 或多个
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }

    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 递增
     *
     * @param key 键
     * @param delta  要增加几(大于0)
     * @return
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 递减
     *
     * @param key 键
     * @param delta  要减少几(小于0)
     * @return
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    /**
     * HashGet
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return 值
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * 获取hashKey对应的所有键值
     *
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     *
     * @param key 键
     * @param map 对应多个键值
     * @return true 成功 false 失败
     */
    public boolean hmset(String key, Map<String, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * HashSet 并设置时间
     *
     * @param key  键
     * @param map  对应多个键值
     * @param time 时间(秒)
     * @return true成功 false失败
     */
    public boolean hmset(String key, Map<String, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除hash表中的值
     *
     * @param key  键 不能为null
     * @param item 项 可以使多个 不能为null
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }

    /**
     * 判断hash表中是否有该项的值
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return true 存在 false不存在
     */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }

    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     *
     * @param key  键
     * @param item 项
     * @param by   要增加几(大于0)
     * @return
     */
    public double hincr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }

    /**
     * hash递减
     *
     * @param key  键
     * @param item 项
     * @param by   要减少记(小于0)
     * @return
     */
    public double hdecr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }

    // ============================set=============================
    /**
     * 根据key获取Set中的所有值
     *
     * @param key 键
     * @return
     */
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据value从一个set中查询,是否存在
     *
     * @param key   键
     * @param value 值
     * @return true 存在 false不存在
     */
    public boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将数据放入set缓存
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 将set数据放入缓存
     *
     * @param key    键
     * @param time   时间(秒)
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSetAndTime(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 获取set缓存的长度
     *
     * @param key 键
     * @return
     */
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 移除值为value的
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 移除的个数
     */
    public long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    // ===============================list=================================

    /**
     * 获取list缓存的内容
     *
     * @param key   键
     * @param start 开始
     * @param end   结束 0 到 -1代表所有值
     * @return
     */
    public List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取list缓存的长度
     *
     * @param key 键
     * @return
     */
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 通过索引 获取list中的值
     *
     * @param key   键
     * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
     * @return
     */
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return
     */
    public boolean lSet(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据索引修改list中的某条数据
     *
     * @param key   键
     * @param index 索引
     * @param value 值
     * @return
     */
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 移除N个值为value
     *
     * @param key   键
     * @param count 移除多少个
     * @param value 值
     * @return 移除的个数
     */
    public long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
}

工具类里面主要是对缓存的新增、删除、查询、设置超时等操作。

    1. 创建测试类
@RestController
@RequestMapping("testRedisUtil")
public class RedisUtilTestController {
    @Autowired
    private RedisUtil redisUtil;

    @GetMapping("/findAll")
    public Object findAll(){
        return redisUtil.get("testRedisUtil-userList");
    }

    @RequestMapping("/saveUser")
    public Object saveUser(SysUser sysUser){
        redisUtil.set("testRedisUtil-userList",sysUser);
        return "添加成功";
    }
}

缓存的key设置为testRedisUtil-userList

测试
  • 通过http://localhost:8088/moyundong/testRedisUtil/saveUser?id=1001&username=test006&password=1111设置缓存
  • 通过http://localhost:8088/moyundong/testRedisUtil/findAll查询缓存
添加RedisConfig配置
@Configuration
public class RedisConfig {
    @Resource
    private LettuceConnectionFactory lettuceConnectionFactory;

    /**
     * @description 自定义的缓存key的生成策略 若想使用这个key
     *              只需要讲注解上keyGenerator的值设置为keyGenerator即可
     */
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuffer sb = new StringBuffer();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    /**
     * RedisTemplate配置
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        // 设置序列化
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置redisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        RedisSerializer<?> stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);// key序列化
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
        redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     * 缓存配置管理器
     */
    @Bean
    public CacheManager cacheManager(LettuceConnectionFactory factory) {
        // 以锁写入的方式创建RedisCacheWriter对象
        RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(factory);
        // 创建默认缓存配置对象
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1)); // 设置缓存有效期一小时;
        RedisCacheManager cacheManager = new RedisCacheManager(writer, config);
        return cacheManager;
    }
}

添加配置文件前,redis里面保存的数据和加上配置文件后,redis里面保存的数据对比如下:


如图所示,加上配置文件后,保存的数据直接就是字符串了。

1介绍
2springboot初体验
3springboot集成jsp
4springboot属性注入
5springboot集成mybatis
6springboot集成lombok
7springboot集成logback日志
8springboot开启全局热部署
9springboot面向切面编程
10springboot文件上传
11springboot文件下载
12springboot自定义拦截器
13springboot打成war包发布
14springboot打成jar包发布
15springboot自定义banner
16springboot配置文件拆分
17springboot定时任务
18springboot定时任务配置详解
19springboot动态定时任务
20springboot集成websocket
21springboot多数据源
22springboot配置druid监听
23springboot自定义注解
24springboot常见注解详解
25springboot接收参数详解
26springboot验证机制@Valid和@Validated
27springboot集成Swagger2
28springboot集成swagger-bootstrap-ui
29springboot集成shiro
30springboot集成shiro(二)
31springboot集成jwt
32springboot集成ActiveMQ
33springboot缓存机制

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值