springboot引入redis的使用

首先,pom文件新增依赖

<!--redis-->
  <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>
<!--Slf4j-->
  <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <version>1.18.20</version>
  </dependency>

yml文件新增配置

redis:
  database: 0
  host: 127.0.0.1
  password:
  port: 6379
  timeout: 5000
  ssl: false

新增启动文件

@SpringBootApplication
public class RedisApplication {
    public static void main(String[] args) {
        // 只需要run一下,就能发布一个springboot应用
        // 相当于之前将web工程发布到tomcat服务器,只是在springboot中集成了tomcat插件
        SpringApplication.run(RedisApplication.class, args);
    }
}

目录结构如图:

新增工具类文件:

@Service
public class RedisUtil {
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 写入缓存
     *
     * @param key   key
     * @param value value
     * @return
     */
    public Boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 写入缓存设置失效时间
     *
     * @param key        key
     * @param value      value
     * @param expireTime expireTime
     * @param timeUnit   timeUnit
     * @return
     */
    public Boolean set(final String key, Object value, Long expireTime, TimeUnit timeUnit) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, timeUnit);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 批量删除对应的value
     *
     * @param keys keys
     */
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(keys);
        }
    }

    /**
     * 批量删除key
     *
     * @param pattern
     */
    public void removePattern(final String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0) {
            redisTemplate.delete(keys);
        }
    }

    /**
     * 删除对应的value
     *
     * @param key
     */
    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }

    /**
     * 判断缓存中是否有对应的value
     *
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 读取缓存
     *
     * @param key
     * @return
     */
    public Object get(final String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }

    /**
     * 哈希 添加
     *
     * @param key
     * @param hashKey
     * @param value
     */
    public void hmSet(String key, Object hashKey, Object value) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.put(key, hashKey, value);
    }

    /**
     * 哈希获取数据
     *
     * @param key
     * @param hashKey
     * @return
     */
    public Object hmGet(String key, Object hashKey) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        return hash.get(key, hashKey);
    }

    /**
     * 列表添加
     *
     * @param k
     * @param v
     */
    public void lPush(String k, Object v) {
        ListOperations<String, Object> list = redisTemplate.opsForList();
        list.rightPush(k, v);
    }

    /**
     * 列表获取
     *
     * @param k
     * @param l
     * @param l1
     * @return
     */
    public List<Object> lRange(String k, long l, long l1) {
        ListOperations<String, Object> list = redisTemplate.opsForList();
        return list.range(k, l, l1);
    }

    /**
     * 集合添加
     *
     * @param key
     * @param value
     */
    public void add(String key, Object value) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add(key, value);
    }

    /**
     * 集合获取
     *
     * @param key
     * @return
     */
    public Set<Object> setMembers(String key) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.members(key);
    }

    /**
     * 有序集合添加
     *
     * @param key
     * @param value
     * @param scoure
     */
    public void zAdd(String key, Object value, double scoure) {
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        zset.add(key, value, scoure);
    }

    /**
     * 有序集合获取
     *
     * @param key
     * @param scoure
     * @param scoure1
     * @return
     */
    public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.rangeByScore(key, scoure, scoure1);
    }

 controller:

@RestController
@RequestMapping("/redis")
@Slf4j
public class TestController {
    @Autowired
    private RedisUtil redisUtil;

    @GetMapping("/set")
    public Boolean setKey(@RequestParam("key") String key, @RequestParam("value") Object value) {
        try {
            redisUtil.set(key, value);
        } catch (Exception e) {
            log.error("redis加入失败:{}", e.getStackTrace());
            return false;
        }
        return true;
    }

    @GetMapping("/get")
    public Object getKey(@RequestParam("key") String key) {
        try {
            return redisUtil.get(key);
        } catch (Exception e) {
            log.error("redis获取失败:{}", e.getStackTrace());
            return false;
        }
    }

}

能成功插入本地redis数据

 启动项目前,先启动本地redis.

这种方式容易有乱码,如上图

对于redis操作,springboot进行了很好的封装,那就是spring data redis。提供了一个高度封装的RedisTemplate类来进行一系列redis操作,连接池自动管理;同时将事务封装操作,交由容器进行处理.。

从图上能看出,出现乱码,因为,引用默认的RedisTemplate,它的默认序列化方式是JDK,而这种方式可读性差。

为了解决以上问题,需进行更改默认序列化:

有两种方式,一种是自定义RedisTemplate类,另一种使用 String RedisTemplate 进行序列化

先讲第二种: String RedisTemplate是spring自带的,直接引用

@Autowired
    private StringRedisTemplate stringRedisTemplate;

spring只限于字符串结构,不建议使用。

再讲自定义redisTemplate类,可以更换序列化方式:

JdkSerializationRedisSerializer。默认方式,无需变更

直接引入即可

@Autowired
    private RedisTemplate redisTemplate;

自定义是更改为非JDK序列化,这里有以下几种选择:

①Jackson

②faskjson

③genericFastJson

其实还有一种是StringRedisSerializer,但是,我们直接引入StringRedisTemplate就解决了,无需自定义,所以这种方式多此一举,可以不讨论,但是key的赋值方式是用了string方式。

目录结构如图:

工具类依旧不动,自动注入redisTemplate

RedisConfig新增文件,代码如下:

这一步会在启动时,重写redisTemplate,所以叫自定义

package com.hyj.config;

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;


@Configuration
@Slf4j
public class RedisConfig {

    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        //为了开发方便,一般使用<String, Object>
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);

//        //Json方式的序列化
//        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//        ObjectMapper objectMapper = new ObjectMapper();
//        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

//        //faskjskn方式序列化
//        FastJson2JsonRedisSerializer fastJson2JsonRedisSerializer = new FastJson2JsonRedisSerializer(Object.class);
//        ObjectMapper objectMapper = new ObjectMapper();
//        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//        fastJson2JsonRedisSerializer.setObjectMapper(objectMapper);

        //String方式的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        GenericFastJsonRedisSerializer jackson2JsonRedisSerializer = new GenericFastJsonRedisSerializer();


        //------设置各模板的序列化方式------
        //设置key的序列化方式为string(不设置的话会乱码)
        template.setKeySerializer(stringRedisSerializer);
        template.setHashKeySerializer(stringRedisSerializer);

        //设置value的序列化方式为json
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);

        template.afterPropertiesSet();

        return template;
    }
}

每一种方式的变更如图:

FastJson2JsonRedisSerializer需要新增文件,内容如下:
package com.hyj.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.util.Assert;

import java.nio.charset.Charset;

public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {

    private ObjectMapper objectMapper = new ObjectMapper();
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    private Class<T> clazz;

    static {
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        ParserConfig.getGlobalInstance().addAccept("com.openailab.oascloud");

    }

    public FastJson2JsonRedisSerializer(Class<T> clazz) {
        super();
        this.clazz = clazz;
    }

    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }
        return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
    }

    public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);

        return JSON.parseObject(str, clazz);
    }

    public void setObjectMapper(ObjectMapper objectMapper) {
        Assert.notNull(objectMapper, "'objectMapper' must not be null");
        this.objectMapper = objectMapper;
    }

    protected JavaType getJavaType(Class<?> clazz) {
        return TypeFactory.defaultInstance().constructType(clazz);
    }
}

 至此,四种方式的序列化讲解完毕。

实际运行,

①Jackson序列化,list类型的数据如图:

读取:Jackson2JsonRedisSerializer报错

②FastJson2JsonRedisSerializer

 读取:

 ③GenericFastJson

下面开始数据读取:

GenericFastJson:

综上所述:推荐FastJson和genericFastJson吧,Jackson肯定是不咋推荐的,反序列化报错

 

 

原文出处:Redis之RedisTemplate配置方式(序列和反序列化)_Redis_服务器之家

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值