Spring Cache 的介绍和实际使用SpringBoot+Redis

导读:本篇文章讲解 Spring Cache 的介绍和实际使用SpringBoot+Redis,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一,Spring Cache介绍

  • Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。
  • Spring Cache提供了一层抽象,底层刻意切换不同的cache实现。具体就是通过CacheManager接口来统一不同的缓存技术。
  • CacheManager是Spring提供的各种缓存技术抽象接口。
  • 针对不同的缓存技术需要实现不同的CacheManager
  • CacheManager通过阅读底层源码不难发现其实是由Map进行实现的缓存,将数据保存在内存中(项目重启数据会清除)
CacheManaer 描述
EhCacheCacheManager 使用EhCache作为缓存技术
GuavaCacheManager 使用Google的GuavaCache作为缓存技术
RedisCacheManager

使用Redis作为缓存技术

二,Spring Cache常用注解

注解 说明
@EnableCaching 开启缓存注解功能

@Cacheable

在方法执行前spring先查看缓存中是否有数据,如果有数据,则直接返回缓数据;若没有数据,调用方法将方法返回值放到缓存中
@CachePut 将方法的返回值放到缓存中
@CacheEvict 将一条或多条数据从缓存中删除

在spring boot项目中,使用缓存技术只需在项目中导入相关缓存技术依赖包,并在启动类上使用@EnableCaching开启缓存支持即可

例如,使用Redis作为缓存技术,只需要导入Spring data Redis的maven坐标即可。


 

//例1,(将方法的返回值放到缓存中)

@CachePut(value = "userCache",key = "#user.id") //key的值是user的id

@PostMapping

public User save(User user){

userService.save(user);

return user;

}

CachePut:     将方法的返回值放入缓存

value: 缓存的名称,每个缓存名称下面可以有多个key

key:缓存的key

//例2,(将一条或多条数据从缓存中删除)

//首先这个有三种写法

//1,@CacheEvict(value = "userCache",key = "#id")

//2,@CacheEvict(value = "userCache",key = "#root.args[0]")

//3,@CacheEvict(value = "userCache",key = "#p0")


@CacheEvict(value = "userCache",key = "#id")

@DeleteMapping("/{id}")

public void delete(@PathVariable Long id){

userService.removeById(id);

}
//例3,@Cacheable(在方法执行前spring先查看缓存中是否有数据,如果有数据,则直接返回缓数据;若没有数据,调用方法将方法返回值放到缓存中)

//@Cacheable(value = "dish",key = "'dish_'+#dish.getCategoryId()+ '_'+ #dish.getStatus()",unless= "#result == null")

@Cacheable(value = "userCache",key = "#id",unless= "#result == null")

@GetMapping("/{id}")

public User getById(@PathVariable Long id){

User user = userService.getById(id);

return user;

}

condition :条件,当不为空时候才会去缓存

unless:当条件成立的时候是不缓存


以上是Spring Cache的简单应用,下面将结合项目进行分享!

1.引入依赖:

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

2.yml配置

      #Redis相关配置
  redis:
    host: 127.0.0.1
    port: 6379
    database: 0  #默认有十六个数据库
    #Redis连接池配置
    jedis:
      pool:
        max-active: 8 #最大连接数
        max-wait: 1ms #连接池最大阻塞等待时间
        max-idle: 4 #连接池中的最大空闲连接
        min-idle: 0 #连接池中的最小空闲连接

#设置缓存有效期
  cache:
    redis:
      time-to-live: 18000000

基于注解进行实现的缓存,将数据缓存到Redis中

@Service
@Slf4j
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {

   @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;


   @Autowired
    CacheManager cacheManager;

    @Override
    @Cacheable(value = "list",key = "'setmeal'+#setmealBo.categoryId+'_'+#setmealBo.Status")
    public R<List<Setmeal>> list(SetmealBo setmealBo) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(setmealBo.getCategoryId() != null, "category_id", setmealBo.getCategoryId())
                .eq(setmealBo.getStatus() != null, "status", setmealBo.getStatus()).orderByDesc("create_time");
        try {
            List list = setmealMapper.selectList(queryWrapper);
            return R.success(list);
        } catch (Exception e) {
            e.printStackTrace();
            return R.error("查询失败!");
        }
    }
}

到此总结一下可能会出现的问题:

问题:DefaultSerializer 需要一个可序列化的有效负载,但收到了一个 [model.Admin] 类型的对象

解决:这个问题是因为实体类没有实现 Serializable 进行序列化,加上即可

@Data
public class R<T> implements Serializable {
    private Integer code; //编码:1成功,0和其它数字为失败

    private String msg; //错误信息

    private T data; //数据

    private Map map = new HashMap(); //动态数据

    public static <T> R<T> success(T object) {
        R<T> r = new R<T>();
        r.data = object;
        r.code = 1;
        return r;
    }

    public static <T> R<T> error(String msg) {
        R r = new R();
        r.msg = msg;
        r.code = 0;
        return r;
    }

    public R<T> add(String key, Object value) {
        this.map.put(key, value);
        return this;
    }

}

补充:

@CacheEvict(value = "list",allEntries = true)

根据value值删除所有缓存值

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/105083.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!