Spring boot redis的使用(二)

Spring boot redis的使用(二)

看过我第一篇介绍spring boot redis的文章的同行们可能发现了一个问题,那就是redis中的value并没有设置过期时间,之前我也是为这个苦恼了半天,发现现成的注解并没有提供过期时间的相关入口,后来经过各种搜索终于找到了解决方法,本篇我们就来介绍如何设置过期时间。

过期时间的设置目前我找到了两个方法:1.通过redis管理器集中配置不同区域下的过期时间;2.通过扩展redis管理器来进行额外传参的方式进行设置,好了废话不多说直接上代码。

1.通过redis管理器集中配置不同区域下的过期时间

2.通过扩展redis管理器来进行额外传参的方式进行设置

2.1编写redis管理器(RedisCacheManager)的扩展类并继承RedisCacheManager,具体代码如下

package com.zxl.examples.catche;

import org.springframework.cache.Cache;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisOperations;

/**
 * Created by Administrator on 2017/7/25.
 */
public class RedisCacheManagerExtend extends RedisCacheManager {

    public RedisCacheManagerExtend(RedisOperations redisOperations) {
        super(redisOperations);
    }

    /**
     * 缓存参数的分隔符
     * 数组元素0=缓存的名称
     * 数组元素1=缓存过期时间TTL
     * 数组元素2=缓存在多少秒开始主动失效来强制刷新
     */
    private String separator = "#";

    /**
     * 缓存主动在失效前强制刷新缓存的时间
     * 单位:秒
     */
    private long preloadSecondTime=0;


    @Override
    public Cache getCache(String name) {

        String[] cacheParams=name.split(this.getSeparator());
        String cacheName = cacheParams[0];

        if(cacheName==null || "".equals(cacheName.trim())){
            return null;
        }

        Long expirationSecondTime = this.computeExpiration(cacheName);

        if(cacheParams.length>1) {
            expirationSecondTime=Long.parseLong(cacheParams[1]);
            this.setDefaultExpiration(expirationSecondTime);
        }
        if(cacheParams.length>2) {
            this.setPreloadSecondTime(Long.parseLong(cacheParams[2]));
        }

        Cache cache = super.getCache(cacheName);
        if(null==cache){
            return null;
        }
        return cache;
//        logger.info("expirationSecondTime:"+expirationSecondTime);
//        CustomizedRedisCache redisCache= new CustomizedRedisCache(
//                cacheName,
//                (this.isUsePrefix() ? this.getCachePrefix().prefix(cacheName) : null),
//                this.getRedisOperations(),
//                expirationSecondTime,
//                preloadSecondTime);
//        return redisCache;

    }

    public String getSeparator() {
        return separator;
    }

    public void setSeparator(String separator) {
        this.separator = separator;
    }

    public long getPreloadSecondTime() {
        return preloadSecondTime;
    }

    public void setPreloadSecondTime(long preloadSecondTime) {
        this.preloadSecondTime = preloadSecondTime;
    }
}
2.2  将redis配置类中的redis管理器生成模式改为new此扩展类,如下图:

2.3 使用的时候在注解传按照以#分隔模式传参,如下图:

就是如此简单,以上两种方式皆可设置redis的过期时间,稍后将贴出整个完整的代码,之前的一章层介绍过@Caching注解的用法,此注解中可传入多个参数使得程序看上去比较复杂,如下图:

对于此种情况我们可以自定义封装成各种业务模式的注解,使得看起来比较轻便,如下图:

以上所有介绍的完整代码如下:

package com.zxl.examples.catche.customannotation;

import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Caching;

import java.lang.annotation.*;

/**
 * Created by Administrator on 2017/7/26.
 */
@Caching(
        put={
                @CachePut(value = "userCache", key = "'user:'+#user.id"),
                @CachePut(value = "userCache", key = "'user:'+#user.username")
        }
)
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface UserSaveCache {
}
package com.zxl.examples.service;

import com.zxl.examples.catche.customannotation.UserSaveCache;
import com.zxl.examples.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2017/7/24.
 */
@Service("userSerivce")
public class UserSerivceImpl {
    @Autowired
    UserRepository userRepository;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @Transactional
    public void addMoreUsers(){
        User user1 = new User();
        user1.setUsername("123");
        user1.setName("123");
        user1.setPassword("123");
        userRepository.save(user1);
        User user2 = new User();
        user2.setUsername("234");
        user2.setName("123");
        user2.setPassword("123");
        userRepository.save(user2);
    }

    public void addMoreList(){
        List userList = new ArrayList();
        User user1 = new User();
        user1.setUsername("345");
        user1.setName("123");
        user1.setPassword("123");
        userList.add(user1);

        User user2 = new User();
        user2.setUsername("456");
        user2.setName("123");
        user2.setPassword("123");
        userList.add(user2);
        userRepository.save(userList);
    }

    //unless-->用于否决缓存更新的,不像condition,该表达只在方法执行之后判断,此时可以拿到返回值result进行判断了
    @Cacheable(value="userCache",key="'user:'+#username",unless = "#result==null")
    public User getUserByUsername(String username){
        User user = null;
        List userlist = userRepository.findByUsername(username);
        if(userlist!=null && userlist.size()>0){
            user = userlist.get(0);
        }
        return user;
    }
//    @Cacheable(value="userCache#120",key="'user:'+#username",unless = "#result==null")
//    public User getUserByUsername(String username){
//        User user = null;
//        List userlist = userRepository.findByUsername(username);
//        if(userlist!=null && userlist.size()>0){
//            user = userlist.get(0);
//        }
//        return user;
//    }

    //allEntries-->是否移除所有数据
    //beforeInvocation-->是调用方法之前移除/还是调用之后移除
    @CacheEvict(value = "userCache",key="'user:'+#user.username")
    public void delUserById(User user){
        userRepository.delete(user);
    }

    public String setUserInRedis(){
        stringRedisTemplate.opsForValue().set("abc","123",60L, TimeUnit.SECONDS);
        return stringRedisTemplate.opsForValue().get("abc");
//        redisTemplate.opsForList();//可直接放入实现序列化的pojo
    }

    public void delUserInRedis(){
        stringRedisTemplate.delete("abc");
    }

    //condition-->满足缓存条件的数据才会放入缓存,condition在调用方法之前和之后都会判断
    @CachePut(value="userCache",key = "#user.username",condition = "#user.username<='100'")
    public User save(User user){
        userRepository.save(user);
        return user;
    }

    @Caching(
            put={
                    @CachePut(value = "userCache", key = "'user:'+#user.id"),
                    @CachePut(value = "userCache", key = "'user:'+#user.username")
            }
    )
    public User addUser(User user){
        userRepository.save(user);
        return user;
    }

    @UserSaveCache
    public User addUser2(User user){
        userRepository.save(user);
        return user;
    }

    @Cacheable(value="userCache",key="'user:'+#username",condition = "#root.target.canCache()",unless = "#result==null")
    public User getUserByUsername2(String username){
        User user = null;
        List userlist = userRepository.findByUsername(username);
        if(userlist!=null && userlist.size()>0){
            user = userlist.get(0);
        }
        return user;
    }

    @Cacheable(value="userCache",key="'user:'+#username",condition = "#root.target.notCache()")
    public User getUserByUsername3(String username){
        User user = null;
        List userlist = userRepository.findByUsername(username);
        if(userlist!=null && userlist.size()>0){
            user = userlist.get(0);
        }
        return user;
    }

    public boolean canCache(){
        return true;
    }

    public boolean notCache(){
        return false;
    }
}

猜你喜欢

转载自blog.csdn.net/long290046464/article/details/76649638