以Redis作为缓存技术,使用SpringBoot、MyBatisPlus来演示@Cacheable、@CachePut、@CacheEvit注解

一、知识点

1、redis是什么?

      key-value的nosql数据库,先存到内存中,会根据一定的策略持久化到磁盘。

2、主要作用有哪些?

     主要用来做缓存数据库和web集群时当做中央缓存存放session。

3、@Cacheable、@CachePut、@CacheEvit、@Caching注解

注解 解释
@Cacheable 在方法执行前Spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放进缓存
@CachePut 无论怎样,都会将方法的缓存值放到缓存中,查询数据库的方法总会被调用
@CacheEvit 将一条或多条数据从缓存中删除
@Caching 可以通过@Caching注解组合多个注解策略在一个方法上

4、注解相关属性

cacheNames/value:指定缓存组件的名称

key:缓存数据使用的key,默认是使用方法参数的值

condition:指定符合条件的情况下缓存

unless:否定缓存,当unless指定的条件为true的时候不进行缓存

5、Spring Boot中配置缓存

spring.cache.type=    //配置要使用的缓存

spring.cache.cache-name=     //程序启动时创建缓存的名称

二、使用工具

1、mysql数据库

2、安装redis

3、安装redis客户端工具:RedisDesktopManager

三、准备工作

创建Spring Boot工程

       在Spring中使用缓存技术的关键是配置CacheManager,而Spring Boot中自动配置了多个CacheManager的实现。

四、编写程序

1、引用依赖


   
      org.springframework.boot
      spring-boot-starter-web
   

   
   
      org.springframework.boot
      spring-boot-starter
   

   
   
      org.springframework.boot
      spring-boot-starter-test
      test
   

   
   
      mysql
      mysql-connector-java
   

   
   
      com.baomidou
      mybatis-plus-boot-starter
      3.3.0
   

   
   
      org.projectlombok
      lombok
      true
   

   
   
      p6spy
      p6spy
      3.8.2
   

   
   
      org.springframework.boot
      spring-boot-starter-data-redis
      2.2.2.RELEASE
   

2、配置application.yml文件

server:
  port: 9999
spring:
  # 配置数据库信息
  datasource:
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:mysql://localhost:3306/mp?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    username: root
    password: 123456
  # 配置redis
  redis:
    database: 15
    host: 127.0.0.1
    port: 6379
  # 配置使用的缓存:redis
  cache:
    type: redis
mybatis-plus:
  configuration:
    # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

 3、编写dao层

package com.test.redis.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.test.redis.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper{
    
}

4、编写service

package com.test.redis.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.test.redis.entity.User;

public interface UserService extends IService {
     User updateUser(User user);

     User getUser(String userId);

     int deleteUser(String userId);
}

实现类:

package com.test.redis.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.test.redis.dao.UserMapper;
import com.test.redis.entity.User;
import com.test.redis.service.UserService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl implements UserService {
    @Override
    @CachePut(cacheNames = "user", key = "#user.id")
    public User updateUser(User user) {
        baseMapper.updateById(user);
        return baseMapper.selectById(user.getId());
    }

    @Override
    @Cacheable(cacheNames = "user", key = "#id",unless="#result == null")
    public User getUser(String id) {
        return baseMapper.selectById(id);
    }

    @Override
    @CacheEvict(cacheNames = "user",key = "#id")
    public int deleteUser(String id) {
        return  baseMapper.deleteById(id);
    }
}

5、编写controller

package com.test.redis.controller;

import com.test.redis.entity.User;
import com.test.redis.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    UserService userService;

    @PutMapping
    public User updateUser(@RequestBody User user) {
        return userService.updateUser(user);
    }

    @GetMapping(value = "/{id}")
    public User getUser(@PathVariable String id) {
        User user = userService.getUser(id);
        return user;
    }

    @DeleteMapping(value = "/{id}")
    public String deleteUser(@PathVariable String id) {
        int i = userService.deleteUser(id);
        if(i==1){
            return "删除成功";
        }
        return "删除失败";
    }
}

6、在启动类上使用@EnableCaching来开启缓存

package com.test.redis;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class RedisApplication {

	public static void main(String[] args) {
		SpringApplication.run(RedisApplication.class, args);
	}

}

 

五、使用postman进行测试

数据表中的数据:

以Redis作为缓存技术,使用SpringBoot、MyBatisPlus来演示@Cacheable、@CachePut、@CacheEvit注解_第1张图片

1、先来从数据库查询一条数据,缓存到redis数据库中(@Cacheable注解 )

以Redis作为缓存技术,使用SpringBoot、MyBatisPlus来演示@Cacheable、@CachePut、@CacheEvit注解_第2张图片

第一次查询之后,经过查询mysql数据库查询出来之后缓存到redis数据库中

以Redis作为缓存技术,使用SpringBoot、MyBatisPlus来演示@Cacheable、@CachePut、@CacheEvit注解_第3张图片

之后再查询该数据,不经过查询数据库的方法,就直接从redis数据库中返回,如下图可看到控制台没有输出sql语句:

以Redis作为缓存技术,使用SpringBoot、MyBatisPlus来演示@Cacheable、@CachePut、@CacheEvit注解_第4张图片

结论:使用@Cacheable注解,第一次查询会经过mysql数据库进行查询,得到结果缓存到redis中。如果redis中已经存在要查询的数据,则就会从redis中取,而不经过mysql数据库。

2、修改一条数据,并更新缓存(@CachePut)

以Redis作为缓存技术,使用SpringBoot、MyBatisPlus来演示@Cacheable、@CachePut、@CacheEvit注解_第5张图片

结论:使用@CachePut注解来更新缓存中的数据,每次都会执行操作数据库的方法,将数据库的数据更新之后,再将新的数据更新到缓存中。

此时,再次查询刚刚更新的数据,可看到控制台中没有输出,这次是在缓存中拿到了最新的数据,如下图:

以Redis作为缓存技术,使用SpringBoot、MyBatisPlus来演示@Cacheable、@CachePut、@CacheEvit注解_第6张图片

3、删除一条数据,并从缓存中将此数据删除(@CacheEvit)

以Redis作为缓存技术,使用SpringBoot、MyBatisPlus来演示@Cacheable、@CachePut、@CacheEvit注解_第7张图片

执行之后,可查看redis中已经将该缓存的数据删除。

六、扩展知识

6.1、Redis默认支持16个数据库可以通过调整Redis的配置文件redis/redis.windows.conf中的databases来修改这一个值,设置完毕后重启Redis便完成配置。

以Redis作为缓存技术,使用SpringBoot、MyBatisPlus来演示@Cacheable、@CachePut、@CacheEvit注解_第8张图片

6.2、在实际项目中可以通过配置文件来指定Redis使用的数据库:

以Redis作为缓存技术,使用SpringBoot、MyBatisPlus来演示@Cacheable、@CachePut、@CacheEvit注解_第9张图片

6.3、Redis不支持自定义数据库的名字,所以每个数据库都以编号命名。这样,就需要开发者记录存储的数据与数据库的对应关系。

6.4、Redis不支持为每个数据库设置不同的访问密码,所以一个客户端要么可以访问全部的数据库,要么全部数据库都没有权限访问。

6.5、清空Redis实例中所有数据库中数据的命令:FLUSHALL

6.6、对于Redis来说,一个Redis实例不适宜存储不同应用程序的数据。一个Redis实例中不同的数据库可用于存放不同环境的数据;不同应用应该使用不同的Redis实例存储数据。

6.7、Redis集群下只有db0,不支持多db。

 

你可能感兴趣的:(Spring,Boot)