Spring Cache缓存技术的使用(内存缓存和Redis缓存)

介绍

 

 常用注解

@Cacheable

  • value、cacheNames:两个等同的参数(cacheNames为Spring 4新增,作为value的别名),用于指定缓存存储的集合名。由于Spring 4中新增了@CacheConfig,因此在Spring 3中原本必须有的value属性,也成为非必需项了
  • key:缓存对象存储在Map集合中的key值,非必需,缺省按照函数的所有参数组合作为key值,若自己配置需使用SpEL表达式,比如:@Cacheable(key = "#p0"):使用函数第一个参数作为缓存的key值,更多关于SpEL表达式的详细内容可参考官方文档
  • condition:缓存对象的条件,非必需,也需使用SpEL表达式,只有满足表达式条件的内容才会被缓存,比如:@Cacheable(key = "#p0", condition = "#p0.length() < 3"),表示只有当第一个参数的长度小于3的时候才会被缓存,若做此配置上面的AAA用户就不会被缓存,读者可自行实验尝试。
  • unless:另外一个缓存条件参数,非必需,需使用SpEL表达式。它不同于condition参数的地方在于它的判断时机,该条件是在函数被调用之后才做判断的,所以它可以通过对result进行判断。
  • keyGenerator:用于指定key生成器,非必需。若需要指定一个自定义的key生成器,我们需要去实现org.springframework.cache.interceptor.KeyGenerator接口,并使用该参数来指定。需要注意的是:该参数与key是互斥的
  • cacheManager:用于指定使用哪个缓存管理器,非必需。只有当有多个时才需要使用
  • cacheResolver:用于指定使用那个缓存解析器,非必需。需通过org.springframework.cache.interceptor.CacheResolver接口来实现自己的缓存解析器,并用该参数指定。
    作用和配置方法:

 

    /** * 根据ID获取Tasklog * @param id * @return */
    @Cacheable(value = CACHE_KEY, key = "#id",condition = "#result != null")
    public Tasklog findById(String id){
        System.out.println("FINDBYID");
        System.out.println("ID:"+id);
        return taskLogMapper.selectById(id);
    }

@CachePut

@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用

作用和配置方法

 

 
    /** * 添加tasklog * @param tasklog * @return */
    @CachePut(value = CACHE_KEY, key = "#tasklog.id")
    public Tasklog create(Tasklog tasklog){
        System.out.println("CREATE");
        System.err.println (tasklog);
        taskLogMapper.insert(tasklog);
        return tasklog;
    }

@CacheEvict

@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空

作用和配置方法

    /** * 根据ID删除Tasklog * @param id */
    @CacheEvict(value = CACHE_KEY, key = "#id")
    public void delete(String id){
        System.out.println("DELETE");
        System.out.println("ID:"+id);
        taskLogMapper.deleteById(id);
    }

@CacheConfig

所有的@Cacheable()里面都有一个value=“xxx”的属性,这显然如果方法多了,写起来也是挺累的,如果可以一次性声明完 那就省事了, 所以,有了@CacheConfig这个配置,@CacheConfig is a class-level annotation that allows to share the cache names,如果你在你的方法写别的名字,那么依然以方法的名字为准。
@CacheConfig是一个类级别的注解。

/** * 测试服务层 */
@Service
@CacheConfig(value = "taskLog")
public class TaskLogService {
 
    @Autowired  private TaskLogMapper taskLogMapper;
    @Autowired  private net.sf.ehcache.CacheManager cacheManager;
 
    /** * 缓存的key */
    public static final String CACHE_KEY   = "taskLog";
 
    /** * 添加tasklog * @param tasklog * @return */
    @CachePut(key = "#tasklog.id")
    public Tasklog create(Tasklog tasklog){
        System.out.println("CREATE");
        System.err.println (tasklog);
        taskLogMapper.insert(tasklog);
        return tasklog;
    }
 
    /** * 根据ID获取Tasklog * @param id * @return */
    @Cacheable(key = "#id")
    public Tasklog findById(String id){
        System.out.println("FINDBYID");
        System.out.println("ID:"+id);
        return taskLogMapper.selectById(id);
    }
}

@Caching

有时候我们可能组合多个Cache注解使用;比如用户新增成功后,我们要添加id–>user;username—>user;email—>user的缓存;此时就需要@Caching组合多个注解标签了。 

@Caching(put = {
@CachePut(value = "user", key = "#user.id"),
@CachePut(value = "user", key = "#user.username"),
@CachePut(value = "user", key = "#user.email")
})
public User save(User user) {
}

自定义缓存注解

比如之前的那个@Caching组合,会让方法上的注解显得整个代码比较乱,此时可以使用自定义注解把这些注解组合到一个注解中,如

@Caching(put = {
    @CachePut(value = "user", key = "#user.id"),
    @CachePut(value = "user", key = "#user.username"),
    @CachePut(value = "user", key = "#user.email")
})
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface UserSaveCache {
}

这样我们在方法上使用如下代码即可,整个代码显得比较干净。

@UserSaveCache
public User save(User user){}

如何使用

使用默认内存缓存

spring-boot-starter-web自带依赖

 

1.Springboot启动类添加注解@EnableCaching(开启缓存)

 2.在对应的controller层使用缓存

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private TUserService userService;
    @Autowired
    private CacheManager cacheManager;

    @RequestMapping("tset01")
    @CachePut(value = "UserCache",key = "#user.id")
    public TUser testo1(@RequestBody TUser user) {
        System.out.println("缓存");
        userService.save(user);
        return user;
    }
}

测试结果

默认缓存(ConcurrentMapCacheManager)

没缓存时

 缓存后

 

使用redis缓存

 依赖

     <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-cache -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
            <version>2.7.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.7.3</version>
        </dependency>

yml配置

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/test?useSSL=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
  redis:
    host: 192.168.126.129
    port: 6379
    database: 0
  cache:
    redis:
      time-to-live: 180000

开启缓存

 使用

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private TUserService userService;
    @Autowired
    private RedisCacheManager cacheManager;

    @RequestMapping("tset01")
    @CachePut(value = "UserCache",key = "#user.id")
    public TUser testo1(@RequestBody TUser user) {
        System.out.println("缓存");
        userService.save(user);
        return user;
    }
}

测试结果

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用SpringCacheRedis可以很方便地实现数据缓存,下面是具体的步骤: 1. 配置Redis 首先需要在项目中引入Redis相关的依赖,如下: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 然后在application.properties文件中配置Redis的连接信息,如下: ```properties spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password=123456 ``` 2. 配置SpringCacheSpringBoot中,可以使用@Cacheable、@CachePut、@CacheEvict等注解来实现缓存,但是需要配置一个CacheManager来管理缓存。可以使用RedisCacheManager来管理Redis缓存,如下: ```java @Configuration @EnableCaching public class CacheConfig extends CachingConfigurerSupport { @Bean public RedisConnectionFactory redisConnectionFactory() { JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(); jedisConnectionFactory.setHostName("127.0.0.1"); jedisConnectionFactory.setPort(6379); jedisConnectionFactory.setPassword("123456"); return jedisConnectionFactory; } @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory()); redisTemplate.setDefaultSerializer(new StringRedisSerializer()); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; } @Bean public CacheManager cacheManager() { RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); RedisCacheManager redisCacheManager = RedisCacheManager.builder(redisConnectionFactory()) .cacheDefaults(redisCacheConfiguration) .transactionAware() .build(); return redisCacheManager; } } ``` 其中,redisConnectionFactory方法是用来创建Redis连接的,redisTemplate方法是用来进行Redis操作的,cacheManager方法是用来创建RedisCacheManager的。 3. 使用缓存 有了上面的配置之后,就可以在项目中使用缓存了。例如,我们可以对一个方法进行缓存,如下: ```java @Service public class UserService { @Autowired private UserRepository userRepository; @Cacheable(value = "userCache", key = "#id") public User getUserById(Long id) { System.out.println("getUserById from DB"); return userRepository.findById(id).orElse(null); } } ``` 在这个例子中,我们使用了@Cacheable注解将getUserById方法进行了缓存,value属性表示缓存的名称,key属性表示缓存的键值。如果缓存中已经有了对应的数据,则直接从缓存中获取数据,否则就从数据库中获取数据,并将数据加入到缓存中。 4. 清除缓存 有时候需要从缓存中清除某些数据,可以使用@CacheEvict注解来实现,如下: ```java @Service public class UserService { @Autowired private UserRepository userRepository; @Cacheable(value = "userCache", key = "#id") public User getUserById(Long id) { System.out.println("getUserById from DB"); return userRepository.findById(id).orElse(null); } @CacheEvict(value = "userCache", key = "#id") public void deleteUserById(Long id) { userRepository.deleteById(id); } } ``` 在这个例子中,我们使用了@CacheEvict注解将deleteUserById方法进行了缓存清除,value属性表示缓存的名称,key属性表示缓存的键值。如果有对应的数据,则从缓存中清除该数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

晚霞虽美不如你

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

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

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

打赏作者

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

抵扣说明:

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

余额充值