springboot 整合缓存 : -> Redis(Aop技术融合) 自动

本文介绍Spring Boot项目中如何利用Redis实现缓存操作,包括手动缓存管理及使用Spring Boot缓存注解的方式。文章详细讲解了@Service、@Autowired与@Resource的区别,并演示了缓存读写的具体代码。

目录

第一步: 先看三层

第二步:使用redis的缓存操作

-> 2.1.1 手动写入redis 缓存操作

->2.1.2 手动redis缓存的测试

-> 2.1.3 知识点1 @Resource与@Autowired区别

---> 1. @Autowired 默认是根据类型注入

--->2. @Resource 根据名字自动注入(默认)

 ->2.2.1 使用springboot自带的缓存技术 @EnableCaching 注解

 -> 2.2.2 缓存注解的使用代码

-> 2.2.3 测试 后发现(使用了默认的jdk代理)

[待续未完, 持续更新]


第一步: 先看三层

1.controller 控制逻辑 

2. service: 数据处理逻辑

3. Dao(mapper) : 数据访问逻辑

业务需求: 从 数据库中取出 放到redis  下次从redis中取出

第二步:使用redis的缓存操作

-> 2.1.1 手动写入redis 缓存操作


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;

/**
 * 模拟 添加 修改 查询 双缓存机制
 * @Author pzy
 * @Description: TODO
 * @Version 0.1.0
 */
@Service
public class TbMenuServiceImpl extends ServiceImpl<TbMenuMapper, TbMenus> implements TbMenuService {


//    @Autowired
//    private RedisTemplate redisTemplate;

    //一般的注入是注入不进去的 
    @Resource(name="redisTemplate")
    private  ValueOperations<Object, Object> vo;

    
    @Override
    public TbMenus selectById(Long id) {
        Object key = vo.get(String.valueOf(id));
        if (key != null){
            System.out.println("我是缓存 key值!!!");
            return (TbMenus) key;
        }
        TbMenus tbMenus = baseMapper.selectById(1L);
        System.out.println("我是数据库 key 值!!!");
        vo.set(String.valueOf(id), tbMenus, Duration.ofSeconds(120));//缓存120秒 一分钟内数据可以不一致

        return tbMenus;
    }


    @Override
    public TbMenus insertMenu(TbMenus tbMenus) {

        baseMapper.insert(tbMenus);
        vo.set(String.valueOf(tbMenus.getId()), tbMenus, Duration.ofSeconds(120));//缓存120秒 一分钟内数据可以不一致

        return tbMenus;
    }

    @Override
    public TbMenus updateMenu(TbMenus tbMenus) {

        baseMapper.updateById(tbMenus);
        vo.set(String.valueOf(tbMenus.getId()), tbMenus, Duration.ofSeconds(120));//缓存120秒 一分钟内数据可以不一致

        return tbMenus;
    }
}

->2.1.2 手动redis缓存的测试

import lombok.SneakyThrows;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

/**
 * 单元测试  有缓存走缓存 没缓存走数据库
 * 模拟 springboot整合 逻辑
 *
 * @Author pzy
 * @Description: TODO
 * @Version 0.1.0
 */
@SpringBootTest
public class RedisAopTest {

//    private TbMenus tbMenus;
    @Autowired
    private TbMenuService tbMenuService;

    @Autowired
    private RedisTemplate redisTemplate;

    TbMenus testAopRedis() {
        TbMenus tbMenus = null;
            ValueOperations<String, TbMenus> value = redisTemplate.opsForValue();
            TbMenus key = value.get("key");
            if (key == null) {
                System.out.println("我是数据库 key 值!!!");
                tbMenus = tbMenuService.selectById(1L);
                value.set("key", tbMenus);

            } else {
                System.out.println("我是缓存 key值!!!");
                tbMenus = key;
            }
            return tbMenus;
    }

    @SneakyThrows
    @Test
    void testSelectById() {

        TbMenus tbMenus = tbMenuService.selectById(1L);
        System.out.println(tbMenus);

    }
    /**
     * 缓存 可以与 数据库不一致
     */
    @Test
    void testUpdateMenu(){
        TbMenus tbMenus = tbMenuService.selectById(1L);
        tbMenus.setName("select res");
        tbMenuService.updateMenu(tbMenus);
    }
    @Test
    void testInsertMenu(){
        TbMenus tbMenus = tbMenuService.selectById(1L);
        tbMenus.setName("select res");
        tbMenus.setPermission("sys:menu:add");
        tbMenuService.insertMenu(tbMenus);
    }

}

-> 2.1.3 知识点1 @Resource与@Autowired区别

---> 1. @Autowired 默认是根据类型注入

@Autowired注解是按照类型(byType)装配依赖对象,

默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。(通过类型匹配找到多个candidate,在没有@Qualifier、@Primary注解的情况下,会使用对象名作为最后的fallback匹配)

--->2. @Resource 根据名字自动注入(默认)

@Resource默认按照ByName自动注入,

由J2EE提供,需要导入包javax.annotation.Resource。

@Resource有两个重要的属性:name和type,

而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。

如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。


 ->2.2.1 使用springboot自带的缓存技术 @EnableCaching 注解

可以缓存方法的返回值
* 由此注解描述的方法是一个切入点方法 由此方法执行时,
* 底层会通过aop机制先从缓存数据中取数据 如果没有再执行方法并将结果放入缓存中
* 全自动执行
* 配合启动类注解@EnableCaching 启动缓存
* 配合@CacheEvict 清除缓存数据

注意:  如果

aop 是根据方法的返回值进行封装, 如果不想要返回值 就需要自己定义aop了 使用自定义注解aop切点 切面 同时可以加上本地缓存+redis缓存技术

 -> 2.2.2 缓存注解的使用代码

 @Cacheable(value = "menusCache", key = "#id")
    @Override
    public TbMenus selectById(Long id) {
        return tbMenuMapper.selectById(1L);
    }

    @CachePut(value = "menusCache", key = "#tbMenus.id")
    @Override
    public TbMenus insertMenu(TbMenus tbMenus) {

        tbMenuMapper.insert(tbMenus);

        return tbMenus;
    }

    @CachePut(value = "menusCache", key = "#tbMenus.id")
    @Override
    public TbMenus updateMenu(TbMenus tbMenus) {

        tbMenuMapper.updateById(tbMenus);

        return tbMenus;
    }

-> 2.2.3 测试 后发现(使用了默认的jdk代理)

 一篇文章 介绍了这些注解 以及内部的方法用处

玩转Spring Cache --- @Cacheable/@CachePut/@CacheEvict注解的原理深度剖析和使用


[待续未完, 持续更新]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pingzhuyan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值