springboot使用注解实现redis缓存

在springboot中两种方式使用缓存,一种是直接通过 RedisTemplate 来使用,另一种是使用 Spring Cache 集成 Redis(也就是注解的方式)。

RedisTemplate 方式不作说明,详细说明实现一下注解方式。

核心三个注解:

  • @Cachable

  • @CachePut

  • @CacheEvict

1.@Cachable

根据方法的请求参数对其结果进行缓存:

  • Key:缓存的 Key,可以为空,如果指定要按照 SPEL 表达式编写,如果不指定,则按照方法的所有参数进行组合。

  • Value:缓存的名称。

  • Condition:缓存的条件,可以为空,使用 SPEL 编写,返回 true 或者 false,只有为 true 才进行缓存。

写法:

@Cacheable(value = "user", key = "#id",condition="#id>1")

public User get(Integer id) {

对应关系:

 针对这一句话进行一次比较:根据方法的请求参数对其结果进行缓存。

 @Cacheable(value = "user", key = "#id",condition="#id>1")
    @Override
    public User get(Integer id) {
        logger.info("进入get方法,当前获取对象:{}", userDao.selectById(id)==null?null:userDao.selectById(id).toString());
        return userDao.selectById(id);
    }

    @Cacheable(value = "test", key = "#id",condition="#id>1")
    @Override
    public String getString(Integer id) {
        logger.info("进入get方法,当前获取对象:{}", userDao.selectById(id)==null?null:userDao.selectById(id).toString());
        return userDao.selectById(id).getUsername();
    }

一个方法返回的是对象,一个方法返回的是字符串。

redis中存储结果:一个存的是字符串,一个存的是对象。(没有进行反序列化处理,大致能看出来不同就行了)

2.@CachePut

根据方法的请求参数对其结果进行缓存:

  • Key:缓存的 Key,可以为空,如果指定要按照 SPEL 表达式编写,如果不指定,则按照方法的所有参数进行组合。

  • Value:缓存的名称。

  • Condition:缓存的条件,可以为空,使用 SPEL 编写,返回 true 或者 false,只有为 true 才进行缓存。

和@Cachable不同的是,@CachePut这个注解可以确保方法被执行,同时方法的返回值也被记录到缓存中。

@Cacheable当重复使用相同参数调用方法的时候,方法本身不会被调用执行,即方法本身被略过了,取而代之的是方法的结果直接从缓存中找到并返回了。

3.@CacheEvict

根据条件对缓存进行清空:

  • Key:缓存的 Key,可以为空,如果指定要按照 SPEL 表达式编写,如果不指定,则按照方法的所有参数进行组合。

  • Value:缓存的名称。

  • Condition:缓存的条件,可以为空,使用 SPEL 编写,返回 true 或者 false,只有为 true 才进行缓存。

  • allEntries:是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存。

  • beforeInvocation:是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存。缺省情况下,如果方法执行抛出异常,则不会清空缓存。

理论知识结束,实践一下:

maven依赖:

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

user实体类:这里必须要序列化,不然进行缓存时会出错。

public class User implements Serializable {
    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

service和dao跳过,直接贴impl代码:注解使用都在这里面

@Service
public class RedisServiceImpl implements IRedisService {

    public static Logger logger = LogManager.getLogger(RedisServiceImpl.class);
    @Autowired
    private UserDao userDao;

    @CachePut(value ="user", key = "#user.id")
    @Override
    public User save(User user) {
        userDao.insert(user);
        logger.info("进入save方法,当前存储对象:{}", user.toString());
        return user;
    }

    @CacheEvict(value="user", key = "#id")
    @Override
    public void delete(int id) {
        userDao.deleteById(id);
        logger.info("进入delete方法,删除成功");
    }

    @Cacheable(value = "user", key = "#id",condition="#id>1")
    @Override
    public User get(Integer id) {
        logger.info("进入get方法,当前获取对象:{}", userDao.selectById(id)==null?null:userDao.selectById(id).toString());
        return userDao.selectById(id);
    }

    @Cacheable(value = "test", key = "#id",condition="#id>1")
    @Override
    public String getString(Integer id) {
        logger.info("进入get方法,当前获取对象:{}", userDao.selectById(id)==null?null:userDao.selectById(id).toString());
        return userDao.selectById(id).getUsername();
    }
}

最后是controller:使用的mp,不是重点,随便造点数据即可。

@RestController
@RequestMapping("redis")
public class RedisController {

    public static Logger logger = LogManager.getLogger(RedisController.class);

    @Autowired
    private IRedisService redisService;

    @GetMapping("/add")
    public void add() {
        User user = new User();
        user.setId(3);
        user.setUsername("abc");
        user.setPassword("abc");
        redisService.save(user);
        logger.info("添加的用户信息:{}", user.toString());
    }

    @GetMapping("/delete")
    public void delete() {
        redisService.delete(3);
    }

    @GetMapping("/get/{id}")
    public void get(@PathVariable("id") String idStr) throws Exception {
        if (StringUtils.isBlank(idStr)) {
            throw new Exception("id为空");
        }
        Integer id = Integer.parseInt(idStr);
        User user = redisService.get(id);
        logger.info("获取的用户信息:{}", user.toString());

    }
    @GetMapping("/getString/{id}")
    public void getString(@PathVariable("id") String idStr) throws Exception {
        if (StringUtils.isBlank(idStr)) {
            throw new Exception("id为空");
        }
        Integer id = Integer.parseInt(idStr);
        redisService.getString(id);

    }
}

启动类上必须要开启注解:

@SpringBootApplication
@EnableCaching
public class ChuanApplication {

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

}

完成,进行接口测试。

猜你喜欢

转载自blog.csdn.net/qq_39404258/article/details/106501965