Springboot的用法之整合Redis

个人博客传送门


redis是一个高性能的缓存中间件,redis可以用作缓存来提高系统的系统,由于redis的本身的一些机制,redis也有很多的使用场景,具体的redis的搭建和使用场景上一篇文章已经讲述,今天就记录下springboot在整合redis的时候的一些操作和客户端的选择。

概念:

  • Jedis:是Redis的Java实现客户端,提供了比较全面的Redis命令的支持,
  • Redisson:实现了分布式和可扩展的Java数据结构。
  • Lettuce:高级Redis客户端,用于线程安全同步,异步和响应使用,支持集群,Sentinel,管道和编码器。

优点:

  • Jedis:比较全面的提供了Redis的操作特性
  • Redisson:促使使用者对Redis的关注分离,提供很多分布式相关操作服务,例如,分布式锁,分布式集合,可通过Redis支持延迟队列
  • Lettuce:主要在一些分布式缓存框架上使用比较多

可伸缩:

  • Jedis:使用阻塞的I/O,且其方法调用都是同步的,程序流需要等到sockets处理完I/O才能执行,不支持异步。Jedis客户端实例不是线程安全的,所以需要通过连接池来使用Jedis。
  • Redisson:基于Netty框架的事件驱动的通信层,其方法调用是异步的。Redisson的API是线程安全的,所以可以操作单个Redisson连接来完成各种操作
  • Lettuce:基于Netty框架的事件驱动的通信层,其方法调用是异步的。Lettuce的API是线程安全的,所以可以操作单个Lettuce连接来完成各种操作

在spring-boot-starter-data-redis中我们可以看到,在springboot2.0以后默认的将链接redis的客户端修改为了Luttuce,那么今天我们就记录下用Luttuce来进行redis的操作,还是在上一节已经创建好的工程的基础上进行搭建。

1.首先我们需要引入spring-boot-starter-data-redis的包用来集成redis,我们可以看到spring-boot-starter-data-redis的pom中引入了如下的包:

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.0.4.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-redis</artifactId>
      <version>2.0.9.RELEASE</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>jcl-over-slf4j</artifactId>
          <groupId>org.slf4j</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>io.lettuce</groupId>
      <artifactId>lettuce-core</artifactId>
      <version>5.0.4.RELEASE</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>

可以看到,在上面的里面引入了Lettuce包和spring-data-redis的包。

2.接下来我们就需要修改application.yml文件,新增上我们的redis的配置信息:

server:
  port: 8080
  servlet:
    context-path: /spring-boot-demo
logging:
  file: /home/kk/spring-boot-demo.log
spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: adminadmin
    timeout: 3000ms
    database: 0
#    lettuce:
#      pool:
#        max-active: 10
#        max-idle: 8
#        max-wait: 3000ms
#        min-idle: 0

我这里注释掉了,链接池的配置因为在Lettuce中的pool已经给给出了默认值,大家可以根据需要自行配置

 public static class Pool {
        private int maxIdle = 8;
        private int minIdle = 0;
        private int maxActive = 8;
        private Duration maxWait = Duration.ofMillis(-1L);

        public Pool() {
        }
}

接下来我们放上一个工具类,这个是我之前一直用的一个,所以直接拷贝来,所有的地方都可以用:RedisUtils.java

package com.kk.demo.common;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author :Mr.kk
 * @date: 2018/12/10 14:24
 */
@Component
public class RedisUtils {

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 存入一个字符串
     * @param key
     * @param value
     * @return
     */
    public boolean insertStrng(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {

        }
        return result;
    }

    /**
     * 存入一个带失效时间的字符串
     * @param key
     * @param value
     * @param expireTime
     * @return
     */
    public boolean setStringTime(final String key, Object value, Long expireTime) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {

        }
        return result;
    }

    /**  查询一个key是否存在
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }

    /** 根据key获取一个string字符串
     * @param key
     * @return
     */
    public String getString(final String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result==null?"":result.toString();
    }

    /** 删除一个string字符串
     * @param key
     */
    public void removeString(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }

    /** 根据keys批量删除
     * batch delete
     * @param keys
     */
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }

    /**
     *  新增一个hash
     * @param key
     * @param hashKey
     * @param value
     */
    public void insertHash(String key, Object hashKey, Object value,long expireTime){
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.put(key,hashKey,value);
        redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
    }

    /**
     *  删除一个hash中的key对应的数值
     */
    public void deleteHash(String key, Object hashKey){
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.delete(key,hashKey);
    }

    /**
     *  新增一个hash不带失效时间
     * @param key
     * @param hashKey
     * @param value
     */
    public void insertHashNotime(String key, Object hashKey, Object value){
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.put(key,hashKey,value);
    }

    /**
     * 查询一个hash
     * @param key
     * @param hashKey
     * @return
     */
    public Object getHash(String key, Object hashKey){
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        return hash.get(key,hashKey);
    }

    /**
     *  设置一个list
     * @param k
     * @param v
     */
    public void insertList(String k,Object v){
        ListOperations<String, Object> list = redisTemplate.opsForList();
        list.rightPush(k,v);
    }

    /**
     *  查询list,并且截取l到l1
     * @param k
     * @param l
     * @param l1
     * @return
     */
    public List<Object> getListByIndex(String k, long l, long l1){
        ListOperations<String, Object> list = redisTemplate.opsForList();
        return list.range(k,l,l1);
    }

    /**
     * 设置一个set
     * @param key
     * @param value
     */
    public void insertSet(String key,Object value){
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add(key,value);
    }

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

    /**
     * 新增一个zset
     * @param key
     * @param value
     * @param scoure
     */
    public void insertZset(String key,Object value,double scoure){
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        zset.add(key,value,scoure);
    }

    /**
     * 获取zset的数据
     * @param key
     * @param scoure
     * @param scoure1
     * @return
     */
    public Set<Object> getZSetByIndex(String key,double scoure,double scoure1){
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.rangeByScore(key, scoure, scoure1);
    }
}

接下来我们需要配置redis调用时候的key和value的序列化方式,从源码中我们可以看出,默认的序列化方式为JdkSerializationRedisSerializer
在这里插入图片描述
会出现如下的问题,通过上线的代码我们知道了,是因为他的序列化方式的问题,因此我们需要修改redis的序列化方式为stringSerializer
RedisConfiguration.java

package com.kk.demo.config;

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.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @author :Mr.kk
 * @date: 2018/12/10 14:23
 */
@Configuration
public class RedisConfiguration{

    /**
     * RedisTemplate配置
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        //定义key序列化方式
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型会出现异常信息;需要我们上面的自定义key生成策略,一般没必要
        template.setKeySerializer(redisSerializer);
        template.setValueSerializer(redisSerializer);
        template.setHashKeySerializer(redisSerializer);
        template.setHashValueSerializer(redisSerializer);
        template.afterPropertiesSet();
        return template;
    }


}

至此,所有的配置工作就全部做完了,现在我们需要写几个接口进行测试了:

  @GetMapping("/insertRedis")
    public void insertRedis(String key,String value){
        redisUtils.insertStrng(key,value);
    }


    @GetMapping("/getRedis")
    public Object getRedis(String key){
        return redisUtils.getString(key);
    }
    
然后启动工程
先在浏览器中输入 
http://127.0.0.1:8080/spring-boot-demo/insertRedis?key=aa&value=bb
然后再输入 
http://127.0.0.1:8080/spring-boot-demo/getRedis?key=aa
会看到返回的数据为bb  这就说明我们的存储和查询已经成功了。 

在这里插入图片描述
欢迎交流学习,转载请注明出处。
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值