SpringBoot坚持学习第六天:集成Redis

一、Redis基本操作

        先导入我的Redis储备知识:从头开始学Redis

        Redis 支持多种数据类型,字符串string、哈希hash、列表list、集合set、有序集合zset。

二、在SpringBoot中集成Redis

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-pool2</artifactId>
</dependency>

        在配置文件中需要配置我们的Redis的服务器地址

# Redis 数据库索引(默认为 0)
spring.redis.database=0
# Redis 服务器地址
spring.redis.host=localhost
# Redis 服务器连接端口
spring.redis.port=6379  
# Redis 服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制) 默认 8
spring.redis.lettuce.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
spring.redis.lettuce.pool.max-wait=-1
# 连接池中的最大空闲连接 默认 8
spring.redis.lettuce.pool.max-idle=8
# 连接池中的最小空闲连接 默认 0
spring.redis.lettuce.pool.min-idle=0

三、具体使用

        首先编写一个实体,需要实现序列化接口,否则不能够加入到缓存。

@Data    //get set hashcode equals toString
@Builder  //build
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private Long id;
    private String username;
    private String password;
}
    @Test
    public void testBuilder() {
        User user = User.builder().id(1L).username("jay").password("3333").build();
        System.out.println(user);
        /**
         * User(id=1, username=jay, password=3333)
         */
    }

原来使用Redis就是这么简单,直接注入就行了。注入后,就能使用Redis客户端提供的相关API方法。

@RunWith(SpringRunner.class)
@SpringBootTest
public class TestRedisTemplate {
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testString() {
        ValueOperations<String, String> operations = redisTemplate.opsForValue();
        operations.set("username", "jay");
        Assert.assertEquals("jay", operations.get("username"));
    }

    @Test
    public void testSaveUser() {
        ValueOperations<String, User> operations = redisTemplate.opsForValue();
        User user = new User(1L,"jay","3333");
        operations.set("mykey",user);
        User u = operations.get("mykey");
        System.out.println(u);
    }
}

有点封装意识的开发人员就会意识到,我们得创建一个类似RedisService这个类,用于封装RedisTemplate这个类。最后提供给客户端使用的都是最简单的接口。

(1)字符串string

  某个字符串  映射 某个值 。 可以理解为Java中的String类型,但是这个字符串对象的值是"abc"。

@Service
public class RedisService {
    private Logger LOGGER = LoggerFactory.getLogger(RedisService.class);

    /**
     * 注入redis的客户端
     */
    @Autowired
    private RedisTemplate redisTemplate;

    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            //获取redis的操作普通键值对的操作对象
            ValueOperations<String, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            LOGGER.error("set error: key {},value {}", key, value, e);
        }
        return result;
    }

    public boolean set(final String key, Object value, Long expireTime) {
        boolean result = false;
        try {
            //获取redis的操作普通键值对的操作对象
            ValueOperations<String, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            //设置过期时间,单位毫秒
            redisTemplate.expire(key, expireTime, TimeUnit.MILLISECONDS);
            result = true;
        } catch (Exception e) {
            LOGGER.error("set error: key {},value {}", key, value, e);
        }
        return result;
    }

   public Object get(final String key) {
        ValueOperations<String, Object> operations = redisTemplate.opsForValue();
        return operations.get(key);
    }

}
    @Test
    public void set(){
        redisService.set("mykey","myValue");
        Assert.assertEquals("myValue",redisService.get("mykey"));
    }
    @Test
    public void testExpire() throws InterruptedException {
        User user = new User(1L, "jay", "3333");
        redisService.set("mykey", user, 100L);
        Thread.sleep(1000);
        Assert.assertNotEquals(user, redisService.get("mykey"));
    }

删除某个字符串 ,先判断这个字符串是否存在,如果存在在删除

    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }

    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }

(2)哈希hash

        keyMap --- fieldKey --- value

    public void hashSet(String key, Object fieldKey, Object value) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.put(key, fieldKey, value);
    }

    public Object hashGet(final String key, final Object fieldKey) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        return hash.get(key, fieldKey);
    }
    @Test
    public void hashSet(){
        redisService.hashSet("jay","age",22);
        Assert.assertEquals(22,redisService.hashGet("jay","age"));
    }

(3)列表List

        有序的队列,支持从左边添加,也支持从队列右侧添加。

        使用 stringRedisTemplate.opsForList() 可以获取 ListOperations<String, String> listOperations Redis 列表对象,该列表是个简单的字符串列表,可以支持从左侧添加,也可以支持从右侧添加

    public void push(final String key, Object value) {
        //String泛型视为list的name,Object泛型视为即将要存储到这个list中的值
        ListOperations<String, Object> list = redisTemplate.opsForList();
        list.rightPush(key, value);
    }

    public List<Object> range(final String key, int start, int end) {
        ListOperations<String, Object> list = redisTemplate.opsForList();
        //获取某个list集合的指定范围索引
        return list.range(key, start, end);
    }
    @Test
    public void testList() {
        redisService.push("myList", "a");
        redisService.push("myList", "b");
        redisService.push("myList", "c");
        List<Object> objectList = redisService.range("myList", 0, -1);
        Assert.assertEquals(3, objectList.size());
    }

 (4)集合set

Redis Set 对外提供的功能与 List 类似是一个列表的功能,特殊之处在于 Set 是可以自动去重的,当你需要存储一个列表数据,又不希望出现重复数据时,Set 是一个很好的选择,并且 Set 提供了判断某个成员是否在一个 Set 集合内的重要接口,这个也是 List 所不能提供的。

    public void setAdd(final String key, Object value) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add(key, value);
    }

    public Set<Object> setMembers(final String key) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.members(key);
    }

    public boolean setIsMember(final String key, final Object value) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.isMember(key, value);
    }
    @Test
    public void testSet() {
        redisService.setAdd("mySet", "a");
        redisService.setAdd("mySet", "b");
        redisService.setAdd("mySet", "b");
        redisService.setAdd("mySet", "c");
        Assert.assertEquals(3, redisService.setMembers("mySet").size());
        Assert.assertTrue(redisService.setIsMember("mySet","c"));
    }

 (5)有序集合zset

使用 Zset 的时候需要额外的输入一个参数 Score,Zset 会自动根据 Score 的值对集合进行排序。也能够取出指定权重范围内的数据。

 public void zsetAdd(final String key, Object value, double score) {
        ZSetOperations zset = redisTemplate.opsForZSet();
        zset.add(key, value, score);
 }
    public Set<Object> zsetRange(final String key, int start, int end) {
        ZSetOperations zset = redisTemplate.opsForZSet();
        return zset.range(key, start, end);
    }

    public Set<Object> zsetRangeByScore(final String key, double score, double score1) {
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.rangeByScore(key, score, score1);
    }
    @Test
    public void testAddZset(){
        redisService.zsetAdd("myZset","a",1);
        redisService.zsetAdd("myZset","c",3);
        redisService.zsetAdd("myZset","b",2);
        //获取所有,顺序是 a b c
        redisService.zsetRange("myZset",0,-1);
        //获取了权重2到3之间的,顺序是 b c
        redisService.zsetRangeByScore("myZset",2,3);
    }

--------------------------------------------------------------------------------------------------------------------------

        再把本次编写的RedisService整个贴上。诶,出租房里真冷,手都快僵了。虽然在重复造轮子,各个公司肯定有这类似的Redis工具类,但是这个过程还是要自己手写一遍,下次见到大牛的Redis工具类才能见贤思齐。

package com.safesoft.redisdemo.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;

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

/**
 * @author jay.zhou
 * @date 2019/1/6
 * @time 13:39
 */
@Service
public class RedisService {
    private Logger LOGGER = LoggerFactory.getLogger(RedisService.class);

    /**
     * 注入redis的客户端
     */
    @Autowired
    private RedisTemplate redisTemplate;

    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            //获取redis的操作普通键值对的操作对象
            ValueOperations<String, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            LOGGER.error("set error: key {},value {}", key, value, e);
        }
        return result;
    }

    public boolean set(final String key, Object value, Long expireTime) {
        boolean result = false;
        try {
            //获取redis的操作普通键值对的操作对象
            ValueOperations<String, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            //设置过期时间
            redisTemplate.expire(key, expireTime, TimeUnit.MILLISECONDS);
            result = true;
        } catch (Exception e) {
            LOGGER.error("set error: key {},value {}", key, value, e);
        }
        return result;
    }

    public Object get(final String key) {
        ValueOperations<String, Object> operations = redisTemplate.opsForValue();
        return operations.get(key);
    }

    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }

    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }

    public void hashSet(String key, Object fieldKey, Object value) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.put(key, fieldKey, value);
    }

    public Object hashGet(final String key, final Object fieldKey) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        return hash.get(key, fieldKey);
    }

    public void push(final String key, Object value) {
        //String泛型视为list的name,Object泛型视为即将要存储到这个list中的值
        ListOperations<String, Object> list = redisTemplate.opsForList();
        list.rightPush(key, value);
    }

    public List<Object> range(final String key, int start, int end) {
        ListOperations<String, Object> list = redisTemplate.opsForList();
        //获取某个list集合的指定范围索引
        return list.range(key, start, end);
    }

    public void setAdd(final String key, Object value) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add(key, value);
    }

    public Set<Object> setMembers(final String key) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.members(key);
    }

    public boolean setIsMember(final String key, final Object value) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.isMember(key, value);
    }

    public void zsetAdd(final String key, Object value, double score) {
        ZSetOperations zset = redisTemplate.opsForZSet();
        zset.add(key, value, score);
    }

    public Set<Object> zsetRange(final String key, int start, int end) {
        ZSetOperations zset = redisTemplate.opsForZSet();
        return zset.range(key, start, end);
    }

    public Set<Object> zsetRangeByScore(final String key, double score, double score1) {
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.rangeByScore(key, score, score1);
    }
}

 

posted @ 2022-07-17 12:15  小大宇  阅读(88)  评论(0编辑  收藏  举报