Springboot2模块系列:cache(注解版缓存)

1 注解

@EnableCaching
@Cacheable
@CacheEvict
@CachePut
@Caching
@CacheConfig
序号注解描述
1EnableCaching开启注解缓存
2CacheConfig配置注解公共参数,如cacheNames,keyGenerator
3Cacheable注解在类或方法上,目标执行前,根据key先从缓存中查询数据,若有则直接返回,若没有,则将该方法返回值存入缓存value中,即将查询的数据自动放入缓存
4CachePut注解在类或方法上,执行方法后,将方法返回值存入缓存value中
5CacheEvict注解在类或方法上,执行方法后,清除缓存中对应key的数据

2 启动配置

启动文件添加注解:@EnableCaching使用

package com.sb;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.scheduling.annotation.EnableScheduling;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SpringBootApplication 
@MapperScan("com.sb.mapper")
@EnableCaching 
public class SbUsageApplication extends SpringBootServletInitializer{
    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application){
        return application.sources(SbUsageApplication.class);
    }
    public static void main(String[] args){
        SpringApplication.run(SbUsageApplication.class, args);
    }
}

3 服务方法注解

3.1 数据库数据缓存

提取变量字符串使用#(井号)获取变量名称,类似于mybatis中取值#{name},Mapper获取数据库数据。
@CacheConfig(cacheNames=“peopleInfos”)配置全局key前缀,使用Redis客户端获取数据时使用,其中xiaoxiao为name值,标记数据键的后缀。

get peopleInfos::xiaoxiao
package com.sb.service.impl;

import java.util.List;
import java.util.Map;
import java.util.HashMap;

import com.sb.service.PeopleInfosService;
import com.sb.mapper.PeopleInfosMapper;
import com.sb.po.PeopleInfos;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@CacheConfig(cacheNames="peopleInfos")
@Service 
@Transactional
public class PeopleInfosServiceImpl implements PeopleInfosService{

    @Autowired 
    private PeopleInfosMapper peopleInfosMapper;

    static Logger logger = LoggerFactory.getLogger(PeopleInfosServiceImpl.class);

    @Override 
    public List<PeopleInfos> getAllPeopleInfos(){
        // List<PeopleInfos> infos = peopleInfosDao.selectAllPeopleInfos();
        List<PeopleInfos> infos = peopleInfosMapper.selectAllPeopleInfos();
        logger.info("test");
        return infos;
    }

    @Cacheable(key="#name")
    @Override
    public Map getPeopleInfosByName(String name){
        Map tempMap = new HashMap();
        List<PeopleInfos> peopleInfos = peopleInfosMapper.selectPeopleInfosByName(name);
        tempMap.put("code", 250);
        tempMap.put("infos", peopleInfos);
        return tempMap;
    }

    @CacheEvict(key="#name")
    @Override 
    public Map deletePeopleInfosByName(String name){
        Map tempMap = new HashMap();
        peopleInfosMapper.deletePeopleInfosByName(name);
        tempMap.put("code", 200);
        tempMap.put("infos", "删除成功");
        return tempMap;
    }

    @CachePut(key="#peopleInfos.name")
    @Override 
    public Map addPeopleInfos(PeopleInfos peopleInfos){
        Map tempMap = new HashMap();
        peopleInfosMapper.addPeopleInfos(peopleInfos);
        tempMap.put("code", 200);
        tempMap.put("infos", "添加成功");
        tempMap.put("datas", peopleInfos);
        return tempMap;
    }
}

3.2 普通数据缓存

缓存普通数据,将获取的数据放到缓存中,如token数据,有时间期限,不用随时调用,当数据过期时,再重新获取。

package com.company.web.service.impl;

import java.util.List;
import java.util.Map;
import java.util.HashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import com.company.web.util.GetToken;
import com.company.web.po.NatureInfos;
import com.company.web.service.GetTokenService;

@CacheConfig(cacheNames = "natureInfos")
@Service
@Transactional
public class GetTokenServiceImpl implements GetTokenService {
    /**
     * 缓存数据 在缓存中存储token
     */
    @Cacheable(key = "#name")
    @Override
    public String getTokenFromCache(String name) {
        Map returnMap = new HashMap();
        GetToken getToken = new GetToken();
        String token = getToken.tokenStr();
        returnMap.put("token", token);
        return token;
    }

    /**
     * 更新token
     */
    @CachePut(key = "#name")
    @Override
    public String getTokenFromAPI(String name) {
        GetToken getToken = new GetToken();
        String token = getToken.tokenStr();
        return token;
    }

    /**
     * 清除缓存数据
     */
    @CacheEvict(key = "#name")
    @Override
    public String clearTokenFromCache(String name) {
        return "success";
    }
}

3.3 缓存普通数据Impl

package com.company.web.service;

import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.company.web.util.GetToken;
import com.company.web.po.NatureInfos;

@Service
@Transactional
public interface GetTokenService {
    public String getTokenFromAPI(String name);

    public String getTokenFromCache(String name);

    public String clearTokenFromCache(String name);
}

4 配置过期时间

使用Redis缓存管理配置缓存过期时间.

package com.sb.config;

import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;

import java.io.Serializable;
import java.time.Duration;
import java.lang.reflect.Method;

@Configuration 
@EnableCaching
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig extends CachingConfigurerSupport{
    @Bean 
    public KeyGenerator wiselyKeyGenerator(){
        return new KeyGenerator(){
            @Override 
            public Object generate(Object target, Method method, Object... params){
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for(Object obj:params){
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    /**
     * springboot 2.x Reidis缓存管理,设置缓存过期时间
     * @param ConnectionFactory
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration
                                                            .defaultCacheConfig()
                                                            .entryTtl(Duration.ofSeconds(60));
        return RedisCacheManager
                .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
                .cacheDefaults(redisCacheConfiguration).build();

    }

    @Bean 
    public RedisTemplate<String, Serializable> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory){
        RedisTemplate<String, Serializable> template = new RedisTemplate<>();
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

}

5 接口

package com.sb.controller;

import com.sb.po.PeopleInfos;
import com.sb.service.PeopleInfosService;
import com.sb.util.TimeGeneratorUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.PathVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@RestController 
@RequestMapping("/api") 
public class PeopleInfosController{
    static Logger logger = LoggerFactory.getLogger(PeopleInfosController.class);
    @Autowired 
    private PeopleInfosService peopleInfosService;
    @Autowired 
    private RedisTemplate redisTemplate;

    @RequestMapping(value="/get-infos/all", method=RequestMethod.GET)
    @ResponseBody 
    public List<PeopleInfos> getAllInfos(){
        List<PeopleInfos> infos = peopleInfosService.getAllPeopleInfos();
        return infos;
    }

    @RequestMapping(value="/add-infos", method=RequestMethod.POST) 
    @ResponseBody 
    public Map addPeopleInfos(@RequestBody PeopleInfos peopleInfos){
        return peopleInfosService.addPeopleInfos(peopleInfos);
    }

    @RequestMapping(value="/delete-by-name", method=RequestMethod.POST) 
    @ResponseBody 
    public Map deletePeopleInfosByName(@RequestBody PeopleInfos peopleInfos){
        // String name = peopleInfos.get("name").toString();
        String name = peopleInfos.getName();
        return peopleInfosService.deletePeopleInfosByName(name);
    }

    @RequestMapping(value="/get-infos-by-name", method=RequestMethod.POST)
    @ResponseBody 
    public Map getInfosByName(@RequestBody PeopleInfos peopleInfos){
        Map tempMap = new HashMap();
        String name = peopleInfos.getName();
        boolean hasKey = redisTemplate.hasKey("people1");
        logger.info("key:{}", hasKey);
        String timeFormat = TimeGeneratorUtil.timeFormatGen("yyyy-MM-dd HH:mm:ss");
        tempMap.put("time", timeFormat);
        tempMap.put("infos", peopleInfosService.getPeopleInfosByName(name));
        return tempMap;
    } 
    @RequestMapping(value = "/token-from-api", method = RequestMethod.GET)
    public String getTokenFromAPI(@RequestParam("name") String name) {
        String token = getTokenService.getTokenFromAPI(name);
        return token;
    }

    @RequestMapping(value = "/token-from-cache", method = RequestMethod.GET)
    public String getTokenFromCache(@RequestParam("name") String name) {
        String token = getTokenService.getTokenFromCache(name);
        Cache cache = cacheManager.getCache("natureInfos");
        System.out.println("cache:" + cache);
        System.out.println("token:" + cache.get("123").toString());
        return token;
        // return cache.get;
    }

    @RequestMapping(value = "/token-clear", method = RequestMethod.DELETE)
    public String clearTokenFromCache(@RequestParam("name") String name) {
        String token = getTokenService.clearTokenFromCache(name);
        return token;
    }
}

6 小结

序号描述
1启动文件使用注解@EnableCaching开启缓存注解功能
2注解在方法上,实现方法返回值:添加到缓存中,从缓存中删除,获取缓存数据
3通过Redis缓存管理器配置缓存中数据过期时间,当缓存中数据过期时,获取数据时,先从数据库(MySQL)获取,并将返回值存到缓存中,待获取相同key值时从缓存中获取
4cacheName和key是为Redis客户端查询数据准备的,通过Springboot将数据存储到缓存中,可以直接从缓存中获取数据,若缓存中没有数据, 则执行函数
5过期时间,将缓存中的数据通过Redis持久化到硬盘中,当数据到达存储期限时,从缓存和Redis删除
6缓存中可以存储非类的数据,如String

【参考文献】
[1]https://blog.csdn.net/justry_deng/article/details/89283664
[2]https://www.cnblogs.com/7788IT/p/11626845.html
[3]https://blog.csdn.net/f641385712/article/details/95169002

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

天然玩家

坚持才能做到极致

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

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

打赏作者

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

抵扣说明:

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

余额充值