3、SpringBoot 整合及操作 Redis

该栏目会系统的介绍 Redis 的知识体系,共分为相关概念、操作指令、主从复制等模块



SpringBoot 整合 Redis

1、导入依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
        <version>2.6.0</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2、配置文件

spring:
  redis:
    host: 127.0.0.1  # 服务器地址
    port: 6379  # 服务器连接端口
    database: 0 # 数据库索引号
    timeout: 1800000  # 连接超时时间(毫秒)
    lettuce:
      pool:
        max-active: 20  # 连接池最大连接数(使用负值表示没有限制)
        max-wait: -1  # 最大阻塞等待时间(负数表示没限制)
        max-idle: 5  # 连接池中的最大空闲连接
        min-idle: 0  # 连接池中的最小空闲连接

3、配置类

@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    private RedisTemplate redisTemplate;

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = 
        					new Jackson2JsonRedisSerializer(Object.class);
        // 解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600))
                .serializeKeysWith(RedisSerializationContext
                			.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext
                	   	.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }

    @Bean
    @Order
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = 
        						new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
        // key序列化方式
        template.setKeySerializer(redisSerializer);
        // value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // value hashmap序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        this.redisTemplate = template;
        return template;
    }

    /**
     * 对hash类型的数据操作
     */
    @Bean
    public HashOperations<String, String, Object> hashOperations() {
        return redisTemplate.opsForHash();
    }

    @Bean
    public HashOperations<String, Integer, Object> hashIntegerOperations() {
        return redisTemplate.opsForHash();
    }

    /**
     * 对redis字符串类型数据操作
     */
    @Bean
    public ValueOperations<String, Object> valueOperations() {
        return redisTemplate.opsForValue();
    }

    /**
     * 对链表类型的数据操作
     */
    @Bean
    public ListOperations<String, Object> listOperations() {
        return redisTemplate.opsForList();
    }

    /**
     * 对无序集合类型的数据操作
     */
    @Bean
    public SetOperations<String, Object> setOperations() {
        return redisTemplate.opsForSet();
    }

    /**
     * 对有序集合类型的数据操作
     */
    @Bean
    public ZSetOperations<String, Object> zSetOperations() {
        return redisTemplate.opsForZSet();
    }
    
}

API 测试

1、字符串相关 API

@SpringBootTest(classes = SpringRedisDemoApplication.class)
class StringOperationTest {

    @Autowired
    private ValueOperations<String, Object> stringOps;

    /**
     * 对字符串类型进行操作
     */
    @Test
    void stringOps() {
        // 保存单个值
        stringOps.set("k1", "v1");
        // 追加
        stringOps.append("k1", "v11");
        // 设置多个值
        Map<String, Object> maps = new HashMap<>();
        maps.put("k2", "v2");
        maps.put("k3", 4);
        stringOps.multiSet(maps);

        // 增量
        final Long value = stringOps.increment("k3");
        System.out.println("增加后的值:" + value);

        // 获取单个值
        final Object v1 = stringOps.get("k1");
        System.out.println("获取的值:" + v1);
        // 获取多个值
        List<String> keys = new ArrayList<>();
        keys.add("k1");
        keys.add("k2");
        final List<Object> values = stringOps.multiGet(keys);
        if (values != null) {
            values.forEach(System.out::println);
        }
    }
    
}

2、列表相关 API

@SpringBootTest(classes = SpringRedisDemoApplication.class)
class ListOperationTest {

    @Autowired
    private ListOperations<String, Object> listOps;

	/**
     * 操作List列表
     */
    @Test
    public void listOps() {
        // 存储单个元素
        listOps.leftPush("scores", "89");
        // 存储多个元素
        List<Object> values = new ArrayList<>();
        values.add("100");
        values.add("89");
        listOps.leftPushAll("scores", values);

        // 修改元素
        listOps.set("scores", 1, "99");

        // 删除元素
        final Long result = listOps.remove("scores", 1, "80");
        System.out.println("删除个数:" + result);

        // 获取元素个数
        final Long size = listOps.size("scores");
        System.out.println("元素个数:" + size);
        // 获取单个元素
        final Object value = listOps.leftPop("scores");
        System.out.println("获取元素值:" + value);
    }

}

3、集合相关 API

@SpringBootTest(classes = SpringRedisDemoApplication.class)
class SetOperationTest {

    @Autowired
    private SetOperations<String, Object> setOps;

	/**
     * 操作set集合
     */
    @Test
    public void setOps() {
        // 添加单个元素
        setOps.add("idCards", "001");
        setOps.add("idCards", "002");
        setOps.add("idCards", "003");
        setOps.add("idCards", "004");

        // 元素弹出
        final List<Object> idCards = setOps.pop("idCards", 1);
        if (idCards != null) {
            idCards.forEach(System.out::println);
        }

        // 删除元素
        final Long result = setOps.remove("idCards", "001");
        System.out.println("删除结果:" + result);

        // 判断集合是否包含元素
        final Boolean flag = setOps.isMember("idCards", "003");
        System.out.println("集合中是否有该元素:" + flag);

        // 获取整个集合
        final Set<Object> idCards2 = setOps.members("idCards");
        if (idCards2 != null) {
            idCards2.forEach(System.out::println);
        }
    }

}

4、有序集合相关 API

@SpringBootTest(classes = SpringRedisDemoApplication.class)
class ZSetOperationTest {

    @Autowired
    private ZSetOperations<String, Object> zsetOps;

	/**
     * 操作zset集合
     */
    @Test
    public void zsetOps() {
        final String KEY = "students";
        // 添加元素
        zsetOps.add(KEY, "ZhangSan", 85);
        zsetOps.add(KEY, "LiSi", 70);
        zsetOps.add(KEY, "John", 75);
        zsetOps.add(KEY, "Near", 96);
        zsetOps.add(KEY, "Kiki", 96);

        // 删除元素
        final Long result = zsetOps.remove(KEY, "Kiki");
        System.out.println("删除结果:" + result);

        // 修改元素分数
        final Double updateScore = zsetOps.incrementScore(KEY, "Near", 100);
        System.out.println("修改后的分数:" + updateScore);

        // 获取元素分数
        final Double score = zsetOps.score(KEY, "John");
        System.out.println("元素分数:" + score);
        // 获取集合中元素个数
        final Long count = zsetOps.count(KEY, 0, 100);
        System.out.println("集合中元素个数:" + count);
        // 获取所有元素
        final Set<Object> members = zsetOps.range(KEY, 0, -1);
        if (members != null) {
            members.forEach(System.out::println);
        }
        System.out.println("=============================");
        // 根据分数区间获取元素
        final Set<ZSetOperations.TypedTuple<Object>> members2 = 
        			zsetOps.rangeByScoreWithScores(KEY, 0, 100);
        if (members2 != null) {
            members2.forEach(member -> 
            	System.out.println(member.getScore() + "==" + member.getValue()));
        }
    }

}

5、哈希表相关 API

@SpringBootTest(classes = SpringRedisDemoApplication.class)
class HashOperationTest {

    @Autowired
    private HashOperations<String, String, Object> hashOps;

	/**
     * 操作Hash类型
     */
    @Test
    public void hashOps() {
        final String KEY = "user";
        // 添加元素
        hashOps.put(KEY, "name", "Near");
        // 添加多个元素
        Map<String, Object> maps = new HashMap<>();
        maps.put("age", 18);
        maps.put("address", "sz");
        maps.put("getder", true);
        hashOps.putAll(KEY, maps);

        // 删除元素
        final Long result = hashOps.delete(KEY, "gender");
        System.out.println("删除结果:" + result);

        // 获取单个元素
        final Object name = hashOps.get(KEY, "name");
        System.out.println("获取结果:" + name);
        // 获取多个元素
        List<String> keys = Arrays.asList("age", "address");
        final List<Object> values = hashOps.multiGet(KEY, keys);
        values.forEach(System.out::println);
        System.out.println("===================");
        // 获取所有元素
        final Map<String, Object> student = hashOps.entries(KEY);
        final Set<Map.Entry<String, Object>> entries = student.entrySet();
        entries.forEach(entry -> System.out.println(
        			entry.getKey() + "====" + entry.getValue()));
    }

}

6、发布订阅

  • 接受类
@Slf4j
public class Receiver {

    private AtomicInteger counter = new AtomicInteger();

    public void receiveMessage(String message) {
        log.info("Received <" + message + ">");
        counter.incrementAndGet();
    }

    public int getCount() {
        return counter.get();
    }
    
}
  • 订阅消息
// 配置订阅消息相关的对象
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

	@Bean
    public Receiver receiver() {
        return new Receiver();
    }

    @Bean
    public MessageListenerAdapter listenerAdapter(Receiver receiver) {
        return new MessageListenerAdapter(receiver, "receiveMessage");
    }

    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                            MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container =new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        // 订阅指定频道使用ChannelTopic,订阅模式使用PatternTopic
        container.addMessageListener(listenerAdapter, new ChannelTopic("news"));
        return container;
    }
    
}
  • 发布消息
@SpringBootTest(classes = SpringRedisDemoApplication.class)
class PublishOperationTest {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

	/**
     * 发布消息
     */
    @Test
    public void publishTest() {
        redisTemplate.convertAndSend("chan1", "Look at things!!");
    }
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值