spring boot 十九 spring cache + redis

本文详细介绍如何在SpringBoot项目中集成Redis缓存,包括依赖导入、注解配置、缓存操作方法及SpEl表达式的使用,通过实例展示缓存读取、更新和删除等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码地址: https://download.youkuaiyun.com/download/zhanglinlang/11133435

spring boot cache 是spring 提供的一套缓存统计接口
只需要用这一套 缓存接口,下面可以兼容 redis ehcahe 实现对缓存的解耦。

spring boot cache 集成 redis 非常简单:
第一 导入 依赖

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

第二步 在 Application类上 加上 缓存启动注解

@SpringBootApplication
@EnableCaching
public class CacheTestApplication {

第三步: 配置redis 数据库:

spring.redis.host=47.93.16.203
#端口号
spring.redis.port=6379
#如果有密码
spring.redis.password=irzhdredis

spring.redis.database=10

第四步:可以直接使用了:

@Service
@CacheConfig(cacheNames = "product") //  cacheNames  代表redis 的一个map 对象。
public class ProductService {
    @Autowired
    private ProductMapper productMapper; // 
    /**
     * spring Cache
     * 注解方法介绍
     * @Cacheable : (查询)有就获取缓存,没有就执行注解方法,并将结果缓存。
     * @CachePut :(插入)将方法的结果缓存。
     * @CacheEvict: (删除) 删除缓存
     * @Caching : (复杂查询,可以将上面的三个方法组合使用)
     *
     * @Cacheable 和 @CachePut 参数介绍:
     * key: 缓存key
     * value: 缓存库。
     * Condition (方法执行前调用): 条件判断: 如果条件为true 不会执行缓存方法(spel 表达式)
     * Unless (方法执行后调用): 条件判断: 如果条件为true  不会执行缓存方法(spel 表达式)
     *
     * @CacheEvict: 参数介绍
     * key value Condition 和前面一样。
     * allEntries 条件判断: 如果为true 删除指定库(value)的所有缓存
     * beforeInvocation 条件判断: 如果为true, 方法执行前删除, false 方法成功后删除
     *
     * SpEl 表达式:
     * #root: 可以理解为当前注解的 方法反射对象。
     * #root.args  当前方法的参数 (例如 root.args[0].name :获取第一个参数的 name 属性 ) 。
     * #root.caches  该方法执行后对应的缓存数据 (例如 root.caches[0].id :获取第一个参数的 id 属性 ) 。
     * #root.target
     * #root.method
     * #root.methodName
     * #result 返回对象
     * #result.id 返回对象的 id (当前对象必须有能够被访问到的 id 属性)
     * #result.getName 返回对象名称。 (当前该对象必须有能够被访问到的 getName 方法名称。)
     * #+参数名 : 获取参数值  例如 (int age,String name)  获取方式 #age #name
     * #a+参数索引  :获取参数值  例如 (int age,String name)  获取方式 #a0  #a1
     * #p+参数所有  :获取参数值  例如 (User user,Product p)  获取方式 #p0.id  #p0.name
     */


    /**
     * Cacheable: 有就获取缓存,没有就执行下面的方法
     * @param id
     * @return
     */
    @Cacheable(key = "#root.methodName+'['+#id+']'")
    public Product getProductById(Long id) {
        Product product = productMapper.getProductById(id);
        System.out.println(product);
        return product;
    }

    /**
     * @CachePut 缓存插入,不检查缓存,只会将方法结果插入到缓存中
     * value: 代表缓存名称,  key 代表主键,
     * p
     * @param product
     * @return
     */
    @CachePut(key = "'getProductById'+'['+#p0.id+']'")
    public Product updateProduct(Product product) {
        int i = productMapper.updateProduct(product);
        return  product;
    }

    /**
     * 删除缓存
     * @param id
     * @return
     */
    @CacheEvict(value="product",key = "'getProductById'+'['+#id+']'")
    public int deleteProductById(Long id) {
        return productMapper.deleteProductById(id);
    }


    /**
     * 删除缓存
     * @return
     */
    @CacheEvict(value="product",allEntries = true,beforeInvocation = true) //清除所有缓存
    public void deleteProductAll() {
        productMapper.deleteProduct();
    }


    //组合注解,可以完成各种骚操作。比如 (从A缓存,存在B缓存,并删除A缓存)
    @Caching(
            cacheable = {@Cacheable(value="product",key="#name")},
            put = {
                    @CachePut(value="product",key="#result.id"),
                    @CachePut(value="product",key="#result.name")
            }
    )
    public Product getProductByName(String productName) {
        return productMapper.getProductByName(productName);
    }

Mapper 模拟数据库,这里使用的是Map

@Component
public class ProductMapper {

    LinkedHashMap<String, Product> map = new LinkedHashMap<>();

    public  Product getProductById(Long id) {
        System.out.println("我是数据库");
        return map.get(id);
    }

    public  int updateProduct(Product product) {
        System.out.println("我是数据库");
        Product remove = map.remove(product.getId());
        map.put(product.getId(), product);
        if (remove != null) {
            return 1;
        }
        return 0;
    }

    public  int deleteProductById(Long id) {
        System.out.println("我是数据库");
        Product remove = map.remove(id);
        return remove != null ? 1 : 0;
    }

    public  Product getProductByName(String productName) {
        System.out.println("我是数据库");
        for (Iterator iterator = map.values().iterator(); iterator.hasNext(); ) {
            Product next = (Product) iterator.next();
            if (next.getName().equals(productName)) {
                return next;
            }
        }
        return null;
    }

    public void deleteProduct() {
        System.out.println("我是数据库");
        map.clear();
    }
}
@Data
public class Product implements Serializable {  //redis会将数据保存到硬盘,所有需要序列化对象
    private String id;
    private String name;
}

测试代码:

@RestController
public class ProductController {

    /**
     * 测试链接:
     * http://localhost:8080/product?id=3&name=bbbbbbb
     * http://localhost:8080/product/3
     * http://localhost:8080/delproduct
     */

    @Autowired
    private ProductService productService;

    @GetMapping("/product/{id}")
    public Product getProduct(@PathVariable("id") Long id) {
        Product product = productService.getProductById(id);
        return product;
    }

    @GetMapping("/product")
    public Product updateProduct(Product product) {
        return productService.updateProduct(product);
    }

    @GetMapping("/delproduct/{id}")
    public String delProduct(@PathVariable(value="id") Long id) {
        productService.deleteProductById(id);
        return "ok";
    }

    @GetMapping("/delproduct")
    public String delProductAll() {
        productService.deleteProductAll();
        return "ok";
    }

    @GetMapping("/product/name/{productName}")
    public Product getEmpByLastName(@PathVariable("productName") String productName){
        return productService.getProductByName(productName);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值