springboot 集成redis 做缓存

一、添加依赖jar包

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

二、新建一个RedisConfig.java类

pakage com.dm.krystal.redis;
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
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.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@Configuration
@EnableCaching//开启注解
public class RedisConfig extends CachingConfigurerSupport {
    @Bean
    @Primary
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofHours(1)); // 设置缓存有效期一小时
        return RedisCacheManager
                .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
                .cacheDefaults(redisCacheConfiguration).build();
    }
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        // set key serializer
        StringRedisSerializer serializer = new StringRedisSerializer();
        // 设置key序列化类,否则key前面会多了一些乱码
        template.setKeySerializer(serializer);
        template.setHashKeySerializer(serializer);
        // fastjson serializer
        GenericFastJsonRedisSerializer fastSerializer = new GenericFastJsonRedisSerializer();
        template.setValueSerializer(fastSerializer);
        template.setHashValueSerializer(fastSerializer);
        // 如果 KeySerializer 或者 ValueSerializer 没有配置,则对应的 KeySerializer、ValueSerializer 才使用这个 Serializer
        template.setDefaultSerializer(fastSerializer);
        LettuceConnectionFactory factory = (LettuceConnectionFactory) redisConnectionFactory;
        // factory
        template.setConnectionFactory(redisConnectionFactory);
        template.afterPropertiesSet();
        return template;
    }
    @Bean
    public RedisFactory redisFactory(RedisConnectionFactory redisConnectionFactory) {
        RedisFactory redisFactory = new RedisFactory();
        redisFactory.setRedisTemplate(redisTemplate(redisConnectionFactory));
        return redisFactory;
    }
}

三、新建一个用于保存数据的RedisFactory.java工具类

package com.dm.krystal.redis;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class RedisFactory {


    private String mutexDefaultExt = "_mutex";
    private long mutextDefaultExpireTime = 60l;

    private RedisTemplate<String, Object> redisTemplate;

    public RedisTemplate<String, Object> getRedisTemplate() {
        return redisTemplate;
    }

    public void setRedisTemplate(
            RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }


    public void saveByStr(final String key, final String value) {
        redisTemplate.execute(new RedisCallback() {
            @Override
            public String doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> redisSerializer = redisTemplate.getStringSerializer();
                connection.set(
                        redisSerializer.serialize(
                                key),
                        redisSerializer.serialize(
                                value));
                return null;
            }
        });
    }


    public String getByStr(final String key) {
        return (String) (redisTemplate.execute(new RedisCallback() {
            @Override
            public String doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> redisSerializer = redisTemplate.getStringSerializer();
                byte[] keys = redisSerializer.serialize(key);
                if (connection.exists(keys)) {
                    byte[] values = connection.get(keys);
                    String retval = redisSerializer.deserialize(values);
                    return retval;
                }
                return null;
            }
        }));
    }


    public String getSetByStr(final String key, final String value) {
        return (String) (redisTemplate.execute(new RedisCallback() {
            @Override
            public String doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> redisSerializer = redisTemplate.getStringSerializer();
                byte[] keys = redisSerializer.serialize(key);
                if (connection.exists(keys)) {
                    byte[] values = redisSerializer.serialize(value);
                    byte[] results = connection.getSet(keys, values);
                    String retval = redisSerializer.deserialize(results);
                    return retval;
                }
                return null;
            }
        }));
    }


    public void saveByStr(final String key, final long timer, final String value) {
        redisTemplate.execute(new RedisCallback() {
            @Override
            public String doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> redisSerializer = redisTemplate.getStringSerializer();
                connection.set(
                        redisSerializer.serialize(
                                key),
                        redisSerializer.serialize(
                                value));
                if (timer != -1) {
                    byte[] keys = redisSerializer.serialize(key);
                    connection.expire(keys, timer);
                }
                return null;
            }
        });
    }


    public <T> void saveByObj(final String key, final T value) {
        redisTemplate.execute(new RedisCallback<T>() {
            @Override
            public T doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<T> redisSerializer = (RedisSerializer<T>) (redisTemplate.getValueSerializer());
                connection.set(
                        redisTemplate.getStringSerializer().serialize(key),
                        redisSerializer.serialize(value));
                return null;
            }
        });
    }


    public <T> T getByObj(final String key) {
        return (T) (redisTemplate.execute(new RedisCallback<T>() {
            @Override
            public T doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] keys = redisTemplate.getStringSerializer().serialize(key);
                if (connection.exists(keys)) {
                    byte[] values = connection.get(keys);
                    RedisSerializer<T> redisSerializer = (RedisSerializer<T>) (redisTemplate.getValueSerializer());
                    T retval = redisSerializer.deserialize(values);
                    return retval;
                }
                return null;
            }
        }));
    }


    public <T> T getSetByObj(final String key, final T value) {
        return (T) (redisTemplate.execute(new RedisCallback<T>() {
            @Override
            public T doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] keys = redisTemplate.getStringSerializer().serialize(key);
                if (connection.exists(keys)) {
                    RedisSerializer<T> redisSerializer = (RedisSerializer<T>) (redisTemplate.getValueSerializer());
                    byte[] values = redisSerializer.serialize(value);
                    byte[] results = connection.getSet(keys, values);
                    T retval = redisSerializer.deserialize(results);
                    return retval;
                }
                return null;
            }
        }));
    }


    public <T> void saveByObj(final String key, final long timer, final T value) {
        redisTemplate.execute(new RedisCallback<T>() {
            @Override
            public T doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<T> redisSerializer = (RedisSerializer<T>) (redisTemplate.getValueSerializer());
                connection.set(
                        redisTemplate.getStringSerializer().serialize(key),
                        redisSerializer.serialize(value));
                if (timer != -1) {
                    byte[] keys = redisTemplate.getStringSerializer().serialize(key);
                    connection.expire(keys, timer);
                }
                return null;
            }
        });
    }


    public Long delete(final String key) {
        return (Long) (redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection)
                    throws DataAccessException {
                return connection.del(
                        redisTemplate.getStringSerializer().serialize(
                                key));
            }
        }));
    }

    public void deleteByPrex(final String name) {
        List<String> allKeys = getAllKeyByName(name);
        allKeys.forEach((key) -> {
            delete(key);
        });
    }
    public List<String> getAllKeyByName(final String name) {
        Set<byte[]> keyBytes = (Set<byte[]>) (redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] keys = redisTemplate.getStringSerializer().serialize(name + "*");
                return connection.keys(keys);
            }
        }));
        if (keyBytes != null && keyBytes.size() > 0) {
            List<String> resultList = new ArrayList<String>();
            for (Iterator<byte[]> it = keyBytes.iterator(); it.hasNext(); ) {
                String keyName = new String(it.next());
                resultList.add(keyName);
            }
            return resultList;
        } else {
            return null;
        }
    }
    public boolean setNX(final String key) {
        return this.setNX(key, "1");
    }
    public boolean setNX(final String key, final String value) {
        return this.setNX(key, -1, value);
    }
    public boolean setNX(final String key, final long timer, final String value) {
        return (boolean) (redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection)
                    throws DataAccessException {
                boolean nxFlag = connection.setNX(
                        redisTemplate.getStringSerializer().serialize(
                                key),
                        redisTemplate.getStringSerializer().serialize(
                                value));
                if (timer != -1) {
                    byte[] keys = redisTemplate.getStringSerializer().serialize(key);
                    connection.expire(keys, timer);
                }
                return nxFlag;
            }
        }));
    }
    public boolean mutexKey(String key, long validTimer, long mutexTimeout) {
        boolean mutexFlag = false;
        try {
            String newKey = key + this.mutexDefaultExt;
            if (mutexTimeout == -1) {
                //无限时等待
                while (true) {
                    long value = System.currentTimeMillis() + validTimer + 1;
                    boolean acquired = this.setNX(newKey, validTimer, String.valueOf(value));
                    if (acquired) {
                        mutexFlag = true;
                        break;
                    } else {
                        long oldValue = Long.valueOf(this.getByStr(newKey));
                        //超时
                        if (oldValue < System.currentTimeMillis()) {
                            long lastValue = Long.valueOf(getSetByStr(newKey, String.valueOf(value)));
                            if (lastValue == oldValue) {
                                // 本线程获取锁成功
                                mutexFlag = true;
                                break;
                            } else {
                                //已被其他线程抢占
                                mutexFlag = false;
                            }
                        } else {
                            mutexFlag = false;
                        }
                    }
                    Thread.sleep(300);
                }
            } else {
                //限时等待
                long curnano = System.nanoTime();
                long nanoMutexTimeout = mutexTimeout * 1000l * 1000l * 1000l;
                do {
                    long value = System.currentTimeMillis() + validTimer + 1;
                    boolean acquired = this.setNX(newKey, validTimer, String.valueOf(value));
                    if (acquired) {
                        mutexFlag = true;
                        break;
                    } else {
                        long oldValue = Long.valueOf(this.getByStr(newKey));
                        //超时
                        if (oldValue < System.currentTimeMillis()) {
                            long lastValue = Long.valueOf(getSetByStr(newKey, String.valueOf(value)));
                            if (lastValue == oldValue) {
                                // 本线程获取锁成功
                                mutexFlag = true;
                                break;
                            } else {
                                //已被其他线程抢占
                                mutexFlag = false;
                            }
                        } else {
                            mutexFlag = false;
                        }
                    }
                    Thread.sleep(300);
                } while ((System.nanoTime() - curnano) < nanoMutexTimeout);
            }
        } catch (Exception ex) {
            mutexFlag = false;
        }
        return mutexFlag;
    }
    public Long mutexRemove(String key) {
        if (key.contains(mutexDefaultExt)) {
            return this.delete(key);
        } else {
            return this.delete(key + mutexDefaultExt);
        }
    }
    public boolean updateLockAndTransactionByStr(final String[] keys, final String[] values) {
        try {
            return (boolean) (redisTemplate.execute(new RedisCallback<Object>() {
                @Override
                public Object doInRedis(RedisConnection connection)
                        throws DataAccessException {
                    RedisSerializer<String> redisSerializer = redisTemplate.getStringSerializer();
                    for (String key : keys) {
                        if (mutexKey(key, mutextDefaultExpireTime, mutextDefaultExpireTime)) {
                            return false;
                        }
                    }
                    for (String key : keys) {
                        connection.watch(redisSerializer.serialize(key + mutexDefaultExt));
                    }
                    connection.multi();
                    for (int i = 0; i < keys.length; i++) {
                        connection.set(redisSerializer.serialize(keys[i] + mutexDefaultExt), redisSerializer.serialize(values[i]));
                    }
                    List<Object> results = connection.exec();
                    if (results == null || results.isEmpty()) {
                        return false;
                    } else {
                        return true;
                    }
                }
            }));
        } catch (Exception ex) {
            return false;
        }
    }
    public boolean updateTransactionByStr(final String[] keys, final String[] values) {
        try {
            return (boolean) (redisTemplate.execute(new RedisCallback<Object>() {
                @Override
                public Object doInRedis(RedisConnection connection)
                        throws DataAccessException {
                    RedisSerializer<String> redisSerializer = redisTemplate.getStringSerializer();
                    for (String key : keys) {
                        connection.watch(redisSerializer.serialize(key + mutexDefaultExt));
                    }
                    connection.multi();
                    for (int i = 0; i < keys.length; i++) {
                        connection.set(redisSerializer.serialize(keys[i] + mutexDefaultExt), redisSerializer.serialize(values[i]));
                    }
                    List<Object> results = connection.exec();
                    if (results == null || results.isEmpty()) {
                        return false;
                    } else {
                        return true;
                    }
                }
            }));
        } catch (Exception ex) {
            return false;
        }
    }
    public boolean updateLockAndTransactionByObj(final String[] keys, final Object[] values) {
        try {
            return (boolean) (redisTemplate.execute(new RedisCallback<Object>() {
                @Override
                public Object doInRedis(RedisConnection connection)
                        throws DataAccessException {
                    for (String key : keys) {
                        if (mutexKey(key, mutextDefaultExpireTime, mutextDefaultExpireTime)) {
                            return false;
                        }
                    }
                    for (String key : keys) {
                        connection.watch(redisTemplate.getStringSerializer().serialize(key + mutexDefaultExt));
                    }
                    connection.multi();
                    for (int i = 0; i < keys.length; i++) {
                        RedisSerializer redisSerializer = (RedisSerializer) (redisTemplate.getValueSerializer());
                        connection.set(redisTemplate.getStringSerializer().serialize(keys[i] + mutexDefaultExt), redisSerializer.serialize(values[i]));
                    }
                    List<Object> results = connection.exec();
                    if (results == null || results.isEmpty()) {
                        return false;
                    } else {
                        return true;
                    }
                }
            }));
        } catch (Exception ex) {
            return false;
        }
    }
    public boolean updateTransactionByObj(final String[] keys, final Object[] values) {
        try {
            return (boolean) (redisTemplate.execute(new RedisCallback<Object>() {
                @Override
                public Object doInRedis(RedisConnection connection)
                        throws DataAccessException {
                    for (String key : keys) {
                        connection.watch(redisTemplate.getStringSerializer().serialize(key + mutexDefaultExt));
                    }
                    connection.multi();
                    for (int i = 0; i < keys.length; i++) {
                        RedisSerializer redisSerializer = (RedisSerializer) (redisTemplate.getValueSerializer());
                        connection.set(redisTemplate.getStringSerializer().serialize(keys[i] + mutexDefaultExt), redisSerializer.serialize(values[i]));
                    }
                    List<Object> results = connection.exec();
                    if (results == null || results.isEmpty()) {
                        return false;
                    } else {
                        return true;
                    }
                }
            }));
        } catch (Exception ex) {
            return false;
        }
    }
    public boolean extPushQueue(final String queueName, final String queueTitle, final long timeout) {
        boolean result = false;
        result = (Boolean) redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] keys = redisTemplate.getStringSerializer().serialize(queueName);
                byte[] values = redisTemplate.getStringSerializer().serialize(queueTitle);
                if (connection.lPush(keys, values) > 0) {
                    if (timeout != -1l) {
                        connection.expire(keys, timeout);
                    }
                    return Boolean.TRUE;
                } else {
                    return Boolean.FALSE;
                }
            }
        });
        return result;
    }
    public boolean extExpireQueue(final String queueName, final long timeout) {
        boolean result = false;
        result = (Boolean) redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] keys = redisTemplate.getStringSerializer().serialize(queueName);
                if (timeout != -1l) {
                    return connection.expire(keys, timeout);
                } else {
                    return true;
                }
            }
        });
        return result;
    }
    public boolean extRemoveQueueMsg(final String queueName, final String msg) {
        boolean result = false;
        Long back = (Long) redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] keys = redisTemplate.getStringSerializer().serialize(queueName);
                byte[] msgs = redisTemplate.getStringSerializer().serialize(msg);
                return connection.lRem(keys, 0l, msgs);
            }
        });
        if (back.longValue() == 0l) {
            result = false;
        } else {
            result = true;
        }
        return result;
    }
    public List<String> extTraversalQueue(final String queueName) {
        List<String> result = null;
        List<byte[]> valueList = (List<byte[]>) redisTemplate.execute(new RedisCallback<List<byte[]>>() {
            @Override
            public List<byte[]> doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] keys = redisTemplate.getStringSerializer().serialize(queueName);
                List<byte[]> valueList = connection.lRange(keys, 0l, -1l);
                return valueList;
            }
        });
        if (valueList != null && valueList.size() > 0) {
            result = new ArrayList<String>();
            for (int i = 0; i < valueList.size(); i++) {
                byte[] valBytes = valueList.get(i);
                result.add(new String(valBytes));
            }
        }
        return result;
    }
    public boolean extTraversalQueueMsg(final String queueName, final String msg) {
        boolean result = false;
        Boolean back = (Boolean) redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] keys = redisTemplate.getStringSerializer().serialize(queueName);
                List<byte[]> valueList = connection.lRange(keys, 0l, -1l);
                Boolean find = Boolean.FALSE;
                if (valueList != null && valueList.size() > 0) {
                    for (int i = 0; i < valueList.size(); i++) {
                        byte[] valBytes = valueList.get(i);
                        String matchKey = new String(valBytes);
                        if (matchKey.equals(msg)) {
                            find = Boolean.TRUE;
                            break;
                        }
                    }
                }
                return find;
            }
        });
        if (!back.booleanValue()) {
            result = false;
        } else {
            result = true;
        }
        return result;
    }
    public boolean extHMapSave(final String key, final String field, final String value) {
        boolean result = false;
        Boolean back = Boolean.FALSE;
        try {
            back = (Boolean) redisTemplate.execute(new RedisCallback<Boolean>() {
                @Override
                public Boolean doInRedis(RedisConnection connection)
                        throws DataAccessException {
                    connection.hSet(
                            redisTemplate.getStringSerializer().serialize(
                                    key),
                            redisTemplate.getStringSerializer().serialize(
                                    field),
                            redisTemplate.getStringSerializer().serialize(
                                    value));
                    return Boolean.TRUE;
                }
            });
        } catch (Exception ex) {
            back = Boolean.FALSE;
        }
        if (!back.booleanValue()) {
            result = false;
        } else {
            result = true;
        }
        return result;
    }
    public String extHMapGet(final String key, final String field) {
        return redisTemplate.execute(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] valBytes = connection.hGet(
                        redisTemplate.getStringSerializer().serialize(
                                key),
                        redisTemplate.getStringSerializer().serialize(
                                field));
                if (valBytes == null || valBytes.length == 0) {
                    return null;
                } else {
                    return new String(valBytes);
                }
            }
        });
    }
}
四、使用redis做缓存
//redis
@RequestMapping("queryUserList")
public  MsgDataBody<List<SysUser>> queryUserList(){
   MsgDataBody<List<SysUser>> msgBody = new MsgDataBody<List<SysUser>>();
    // MsgBody msgBody=new MsgBody();
    msgBody.setCode(Constant.Error.getCode());
    msgBody.setMsg("获取数据失败");
    SysUser sysUser=new SysUser();
    List<SysUser> list =new ArrayList<>();
    try{
        if(redisFactory.getByObj("data")!=null){
            JSONArray jsonArray = JSONArray.fromObject(redisFactory.getByObj("data"));//将json字符串转为json对象
             list = (List<SysUser>)JSONArray.toCollection(jsonArray,SysUser.class) ;//将 json 对象转为list 数组
            System.out.println("iam cache 111");
       }else {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<SysUser>();
       // wrapper.eq("id","1");
         list=iSysUserService.selectList(wrapper);
         redisFactory.saveByObj("data",60*15,list);//60.15数据在redis存活的时间
          System.out.println("iam query111");
        }
        msgBody.setData(list);
        msgBody.setCode(Constant.Success.getCode());
        msgBody.setMsg("获取数据成功");
    }catch (RuntimeException e){
        msgBody.setCode(Constant.Error.getCode());
    }
    return  msgBody;
}

五、注意(其实这个和主题没啥关系)

上面使用JSONArray.fromObject要引入import net.sf.json.JSONArray, 而不是import com.alibaba.fastjson.JSONArray,idea每次导包时候都是默认引用import com.alibaba.fastjson.JSONArray出问题。

猜你喜欢

转载自blog.csdn.net/sinat_34338162/article/details/84330919