链表结构是Redis中一个常用的结构,他可以存储多个字符串,而且是有序的。Redis链表是双向的,因此可以从左到右也可以从右到左遍历它存储的节点。使用链表结构就意味着读性能的丧失,其优势在于插入和删除的便利。
SpringBoot中使用RedisTemplate执行Redis基本命令
在application.properties或application.yml文件中配置Redis
spring:
redis:
host: 127.0.0.1
port: 6379
编写代码
package com.heaven.redis; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.connection.RedisListCommands; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.test.context.junit4.SpringRunner; import redis.clients.jedis.Jedis; import java.io.UnsupportedEncodingException; import java.util.*; @RunWith(SpringRunner.class) @SpringBootTest @Slf4j class RedisApplicationTests { @Autowired RedisTemplate redisTemplate; @Test void testLinkedList() { //设置生成key value的序列化策略 RedisSerializer<String> stringSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringSerializer); redisTemplate.setValueSerializer(stringSerializer); redisTemplate.setHashKeySerializer(stringSerializer); redisTemplate.setHashValueSerializer(stringSerializer); //删除list以便反复测试() redisTemplate.delete("list"); //将node3从左边插入链表(lpush) redisTemplate.opsForList().leftPush("list","node3"); List<String> nodeList = new ArrayList<>(); for(int i=2;i>=1;i--){ nodeList.add("node"+i); } //将多个node从左边插入链表(lpush) redisTemplate.opsForList().leftPushAll("list",nodeList); //从链表右边插入一个node(rpush) redisTemplate.opsForList().rightPush("list","node4"); //获取下标为0的节点(lindex) String node1 = (String) redisTemplate.opsForList().index("list", 0); log.info("node1====="+node1); //获取链表长度(llen) Long size = redisTemplate.opsForList().size("list"); log.info("size=========="+size); //从左边弹出一个节点(lpop) String lpop = (String) redisTemplate.opsForList().leftPop("list"); log.info("lpop=========="+lpop); //从右边弹出一个节点(rpop) String rpop = (String) redisTemplate.opsForList().rightPop("list"); log.info("rpop=========="+rpop); try { //在node2前插入一个节点(linsert 需要使用更为底层的命令操作) redisTemplate.getConnectionFactory().getConnection().lInsert("list".getBytes("utf-8"), RedisListCommands.Position.BEFORE,"node2".getBytes("utf-8"),"before_node".getBytes("utf-8")); //在node2之后插入一个节点(linsert 需要使用更为底层的命令操作) redisTemplate.getConnectionFactory().getConnection().lInsert("list".getBytes("utf-8"), RedisListCommands.Position.AFTER,"node2".getBytes("utf-8"),"after_node".getBytes("utf-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } //判断list是否存在,若存在则在左侧插入节点(lpushx) redisTemplate.opsForList().leftPushIfPresent("list","start"); //判断list是否存在,若存在则在右侧插入节点(rpushx) redisTemplate.opsForList().rightPushIfPresent("list","end"); //获取下标0到3的节点元素(lrange) List<String> ranges = redisTemplate.opsForList().range("list", 0, 10); for(String range : ranges){ log.info("range========"+range); } for(int i=0;i<3;i++){ nodeList.add("node"); } //从左侧插入3个值为node的节点(lpush) redisTemplate.opsForList().leftPushAll("list",nodeList); //从左到右删除至多三个值为node的节点(lrem) redisTemplate.opsForList().remove("list",3,"node"); //给链表下标为0的节点设置新值(lset) redisTemplate.opsForList().set("list",0,"new_node_value"); log.info("nodeList==="+redisTemplate.opsForList().range("list",0,redisTemplate.opsForList().size("list"))); } }
运行结果