话说Redis支持String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Zset(有序集合)五种数据类型,在java语言中,Redis对应的架包也有不少,最常用的当属Jedis、Lettuce和Redisson这三款框架,其中Jedis不仅小巧,而且实现简单,使用简单。下面就使用SpringBoot2.1.4整合Jedis框架,来把Redis所支持的数据类型一一写来。
首先,在pom文件中引入Jedis架包和测试架包;
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
这里需要加入Jedis client的版本号,不然会报错,这是需要注意的地方;不加回报:
Caused by: java.lang.ClassNotFoundException: redis.clients.jedis.Jedis
String(字符串类型)相关操作方法;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
/**
* 使用Jedis操作字符串示例
* @author
* @date 2019年12月23日
*/
public class StringTestDemo {
private static Logger log = LoggerFactory.getLogger(StringTestDemo.class);
@Test
public void operate(){
Jedis jedis = new Jedis("localhost", 6379);
//如果返回 pang 代表链接成功
log.info("1. jedis.ping():" + jedis.ping());
//设置key0的值 123456
jedis.set("key0", "123456");
//返回数据类型 string
log.info("2. jedis.type(key0): " + jedis.type("key0"));
//get key
log.info("3. jedis.get(key0): " + jedis.get("key0"));
// key是否存在
log.info("4. jedis.exists(key0):" + jedis.exists("key0"));
//返回key的长度
log.info("5. jedis.strlen(key0): " + jedis.strlen("key0"));
//返回截取字符串, 范围 0,-1 表示截取全部
log.info("6. jedis.getrange(key0): " + jedis.getrange("key0", 0, -1));
//返回截取字符串, 范围 1,4 表示从表示区间[1,4]
log.info("7. jedis.getrange(key0): " + jedis.getrange("key0", 1, 4));
//追加
log.info("8. jedis.append(key0): " + jedis.append("key0", "appendStr"));
log.info("9. jedis.get(key0): " + jedis.get("key0"));
//重命名
jedis.rename("key0", "key0_new");
//判断key 是否存在
log.info("10. jedis.exists(key0): " + jedis.exists("key0"));
//批量插入
jedis.mset("key1", "val1", "key2", "val2", "key3", "100");
//批量取出
log.info("11. jedis.mget(key1,key2,key3): " + jedis.mget("key1", "key2", "key3"));
//删除
log.info("12. jedis.del(key1): " + jedis.del("key1"));
log.info("13. jedis.exists(key1): " + jedis.exists("key1"));
//取出旧值 并set新值
log.info("14. jedis.getSet(key2): " + jedis.getSet("key2", "value3"));
//自增1 要求数值类型
log.info("15. jedis.incr(key3): " + jedis.incr("key3"));
//自增15 要求数值类型
log.info("16. jedis.incrBy(key3): " + jedis.incrBy("key3", 15));
//自减1 要求数值类型
log.info("17. jedis.decr(key3): " + jedis.decr("key3"));
//自减5 要求数值类型
log.info("18. jedis.decrBy(key3): " + jedis.decrBy("key3", 15));
//增加浮点类型
log.info("19. jedis.incrByFloat(key3): " + jedis.incrByFloat("key3", 1.1));
//返回0 只有在key不存在的时候才设置
log.info("20. jedis.setnx(key3): " + jedis.setnx("key3", "existVal"));
log.info("21. jedis.get(key3): " + jedis.get("key3"));// 3.1
//只有key都不存在的时候才设置,这里返回 null
log.info("22. jedis.msetnx(key2,key3): " + jedis.msetnx("key2", "exists1", "key3", "exists2"));
log.info("23. jedis.mget(key2,key3): " + jedis.mget("key2", "key3"));
//设置key 2 秒后失效
jedis.setex("key4", 2, "2 seconds is no Val");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 2 seconds is no Val
log.info("25. jedis.get(key4): " + jedis.get("key4"));
jedis.set("key6", "123456789");
//下标从0开始,从第三位开始,将新值覆盖旧值
jedis.setrange("key6", 3, "abcdefg");
//返回:123abcdefg
log.info("26. jedis.get(key6): " + jedis.get("key6"));
//返回所有匹配的key
log.info("27. jedis.get(key*): " + jedis.keys("key*"));
jedis.close();
}
}
Hash(哈希类型)相关的操作方法;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
/**
* Hash相关操作方法
* @author
* @date 2019年12月23日
*/
public class HashDemo {
private static Logger log = LoggerFactory.getLogger(HashDemo.class);
/**
* Redis hash 是一个string类型的field和value的映射表,
* hash特别适合用于存储对象。
* Redis 中每个 hash 可以存储 2^32 - 1 键值对(40多亿)
*/
@Test
public void operate() {
Jedis jedis = new Jedis("localhost");
jedis.del("config");
//设置hash的 field-value 对
jedis.hset("config", "ip", "127.0.0.1");
//取得hash的 field的关联的value值
log.info("0. jedis.hget(): " + jedis.hget("config", "ip"));
//取得类型:hash
log.info("0. jedis.type(): " + jedis.type("config"));
//批量添加 field-value 对,参数为java map
Map<String, String> configFields = new HashMap<String, String>();
configFields.put("port", "8080");
configFields.put("maxalive", "3600");
configFields.put("weight", "1.0");
//执行批量添加
jedis.hmset("config", configFields);
//批量获取:取得全部 field-value 对,返回 java map
log.info("1. jedis.hgetAll(): " + jedis.hgetAll("config"));
//批量获取:取得部分 field对应的value,返回 java map
log.info("2. jedis.hmget(): " + jedis.hmget("config", "ip", "port"));
//浮点数增加: 类似于String的 incrByFloat
jedis.hincrByFloat("config", "weight", 1.2);
log.info("3. jedis.hget(weight): " + jedis.hget("config", "weight"));
//获取所有的key
log.info("4. jedis.hkeys(config): " + jedis.hkeys("config"));
//获取所有的val
log.info("5. jedis.hvals(config): " + jedis.hvals("config"));
//获取长度
log.info("6. jedis.hlen(): " + jedis.hlen("config"));
//判断field是否存在
log.info("7. jedis.hexists(weight): " + jedis.hexists("config", "weight"));
//删除一个field
jedis.hdel("config", "weight");
log.info("8. jedis.hexists(weight): " + jedis.hexists("config", "weight"));
//删除后,查看是否存在
jedis.del("config");
log.info("9. jedis.hexists(weight): " + jedis.hexists("config", "weight"));
jedis.close();
}
}
List(字符串列表类型)相关的操作方法;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
/**
* list测试,list中只能存字符串
* @author
* @date 2019年12月23日
*/
public class ListDemo {
private static Logger log = LoggerFactory.getLogger(ListDemo.class);
/**
* Redis列表是简单的字符串列表,按照插入顺序排序。
* 可以添加一个元素到列表的头部(左边)或者尾部(右边)
*/
@Test
public void operate() {
Jedis jedis = new Jedis("localhost", 6379);
//从list尾部添加3个元素
jedis.rpush("list1", "zhangsan", "lisi", "wangwu");
//取得类型, list
log.info("1. jedis.type(): " +jedis.type("list1"));
//遍历区间[0,-1],取得全部的元素
log.info("2. jedis.lrange(0,-1): " +jedis.lrange("list1", 0, -1));
//遍历区间[1,2],取得区间的元素
log.info("3. jedis.lrange(1,2): " +jedis.lrange("list1", 1, 2));
//获取list长度
log.info("4. jedis.llen(list1): " +jedis.llen("list1"));
//获取下标为 1 的元素
log.info("5. jedis.lindex(list1,1): " +jedis.lindex("list1", 1));
//左侧弹出元素
log.info("6. jedis.lpop(): " +jedis.lpop("list1"));
//右侧弹出元素
log.info("7. jedis.rpop(): " +jedis.rpop("list1"));
//设置下标为0的元素val
jedis.lset("list1", 0, "lisi2");
//最后,遍历区间[0,-1],取得全部的元素
log.info("8. jedis.lrange(0,-1): " + jedis.lrange("list1", 0, -1));
//清除list1中所有的元素
jedis.del("list1");
log.info("9. jedis.del(list1):" + jedis.lrange("list1", 0, -1));
jedis.close();
}
}
Set(集合类型)相关的操作方法;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
/**
* set测试,是不重复的string无序集合
* @author
* @date 2019年12月23日
*/
public class SetDemo {
private static Logger log = LoggerFactory.getLogger(SetDemo.class);
/**
* Redis 的 Set 是 String 类型的无序集合。
* 集合成员是唯一的,这就意味着集合中不能出现重复的数据。
* Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
* 集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储40多亿个成员)。
*/
@Test
public void operate() {
Jedis jedis = new Jedis("localhost");
jedis.del("set1");
log.info("1. jedis.type(): " + jedis.type("set1"));
//sadd函数: 向集合添加元素
jedis.sadd("set1", "user01", "user02", "user03");
//smembers函数: 遍历所有元素
log.info("2. jedis.smembers(): " + jedis.smembers("set1"));
//scard函数: 获取集合元素个数
log.info("3. jedis.scard(): " + jedis.scard("set1"));
//sismember 判断是否是集合元素
log.info("4. jedis.sismember(user04): " + jedis.sismember("set1", "user04"));
//srem函数:移除元素
log.info("5. jedis.srem(): " + jedis.srem("set1", "user02", "user01"));
//smembers函数: 遍历所有元素
log.info("6. jedis.smembers(): " + jedis.smembers("set1"));
jedis.close();
}
}
ZSet(有序集合类型)相关的操作方法;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* zset测试
* @author
* @date 2019年12月23日
*/
public class ZSetDemo {
private static Logger log = LoggerFactory.getLogger(ZSetDemo.class);
/**
* Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。
* 不同的是每个元素都会关联一个double类型的分数。
* redis正是通过分数来为集合中的成员进行从小到大的排序。
* 有序集合的成员是唯一的,但分数(score)却可以重复。
* 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
* 集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储40多亿个成员)。
*/
@Test
public void operateZset() {
Jedis jedis = new Jedis("localhost");
Map<String, Double> members = new HashMap<String, Double>();
members.put("u01", 1000.0);
members.put("u02", 2000.0);
members.put("u03", 3000.0);
members.put("u04", 13000.0);
members.put("u05", 23000.0);
//批量添加元素
jedis.zadd("salary", members);
//类型,zset
log.info("1. jedis.type(): " + jedis.type("salary"));
//获取集合元素个数
log.info("2. jedis.zcard(): " + jedis.zcard("salary"));
//按照下标[起,止]遍历元素
log.info("3. jedis.zrange(): " + jedis.zrange("salary", 0, -1));
//按照下标[起,止]倒序遍历元素
log.info("4. jedis.zrevrange(): " + jedis.zrevrange("salary", 0, -1));
//按照分数(薪资)[起,止]遍历元素
log.info("5. jedis.zrangeByScore(): " + jedis.zrangeByScore("salary", 1000, 10000));
//按照薪资[起,止]遍历元素,带分数返回
Set<Tuple> res0 = jedis.zrangeByScoreWithScores("salary", 1000, 10000);
for (Tuple temp : res0) {
log.info("6. Tuple.get(): " + temp.getElement() + " -> " + temp.getScore());
}
//按照分数[起,止]倒序遍历元素
log.info("7. jedis.zrevrangeByScore(): " + jedis.zrevrangeByScore("salary", 1000, 4000));
//获取元素[起,止]分数区间的元素数量
log.info("8. jedis.zcount(): " + jedis.zcount("salary", 1000, 4000));
//获取元素score值:薪资
log.info("9. jedis.zscore(): " + jedis.zscore("salary", "u01"));
//获取元素下标
log.info("10. jedis.zrank(u01): " + jedis.zrank("salary", "u01"));
//倒序获取元素下标
log.info("11. jedis.zrevrank(u01): " + jedis.zrevrank("salary", "u01"));
//删除元素
log.info("12. jedis.zrem(): " + jedis.zrem("salary", "u01", "u02"));
//删除元素,通过下标范围
log.info("13. jedis.zremrangeByRank(): " + jedis.zremrangeByRank("salary", 0, 1));
//删除元素,通过分数范围
log.info("14. jedis.zremrangeByScore(): " + jedis.zremrangeByScore("salary", 20000, 30000));
//按照下标[起,止]遍历元素
log.info("15. jedis.zrange(): " + jedis.zrange("salary", 0, -1));
Map<String, Double> members2 = new HashMap<String, Double>();
members2.put("u11", 1136.0);
members2.put("u12", 2212.0);
members2.put("u13", 3324.0);
//批量添加元素
jedis.zadd("salary", members2);
//增加指定分数
log.info("16. jedis.zincrby(10000): " + jedis.zincrby("salary", 10000, "u13"));
//按照下标[起,止]遍历元素
log.info("17. jedis.zrange(): " + jedis.zrange("salary", 0, -1));
jedis.close();
}
}
别人写的demo,看起来很简单,自己来一遍,就会遇到这样那样意想不到的问题,并没有想得那么顺利;不管怎么样,还是按照别人的例子再来一遍比较好。这么多的方法,要靠不断地使用才能加深印象。
参考资料:
https://blog.csdn.net/chl87783255/article/details/98177040
https://www.cnblogs.com/crazymakercircle/p/9904544.html