set get incr decr
字符串类型:实际上可以是字符串(包括XML JSON),Jedis,还有数字(整形 浮点数),二进制(图片 音频 视频),最大不能超过512MB,==用string类型存储单个变量==
设置值
set age 23 ex 10 //10秒后过期 px 10000 毫秒过期 *** ex:expire
批量设值:mset country china city beijing(了解)
获取值
get age //存在则返回value, 不存在返回nil ***
批量获取:mget country city address //返回china beigjin, address为nil(了解)
注意:若没有mget命令,则要执行n次get命令
常用命令
incr age //必须为整数自加1,非整数返回错误,无age键从0自增返回1 increase ***
decr age //整数age减1 decrease ***
incrby age 2 //整数age+2
decrby age 2 //整数age -2
incrbyfloat score 1.1 //浮点型score+1.1
清除库
清除当前库:flushdb
清除所有库:flushall
换库
select 2 :切换db2库
select 0 :切换db0库
/*
* <>:T E K V
* T:Type
* E:Elements
* K:key
* V:value
* */
public class RedisUtil {
//Jedis:等同于Connection
public static Jedis getJedis() {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(500);
config.setMaxIdle(5);
config.setMaxWaitMillis(100);
JedisPool jedisPool =
new JedisPool(config, "192.168.60.130", 6379, 1000, "123456");
Jedis jedis = jedisPool.getResource();
return jedis;
}
//把Map转换成Map
public static Map mapToMap(Map map) {
Map data = new HashMap();
for (Map.Entry m : map.entrySet()) {
data.put(m.getKey(), m.getValue() + "");
}
return data;
}
//把数据库查询出来的数据存储到Redis中
public static void dbToRedis(List data, Jedis jedis, int index, String keyPattern) {
//选db库
jedis.select(index);
Map map = new HashMap<>();
for (T t : data) {
//把对象的数据放入到Map中
BeanUtil.beanToMap(t, map, false, true);
//Map转换成Map
Map tempData = mapToMap(map);
jedis.hmset(keyPattern + jedis.incr("index"), tempData);
}
}
//把Redis数据查询出来封装到对象中
public static List redisToJava(Class clazz, Jedis jedis, int index, String keyPattern) {
//选库
jedis.select(index);
//获取满足条件的key
Set keys = jedis.keys(keyPattern);
List data = new ArrayList();
for (String key : keys) {
Map map = jedis.hgetAll(key);
T t = BeanUtil.mapToBean(map, clazz,
false, new CopyOptions().ignoreNullValue());
data.add(t);
}
return data;
}
}
Jedis jedis = RedisUtil.getJedis();
//测试string类型
@Test
public void test01() {
jedis.select(6);
jedis.set("name", "张三");
String name = jedis.get("name");
System.out.println(name);
}
//测试hash类型
@Test
public void test02() {
jedis.select(1);
Map map = new HashMap();
map.put("name", "张三");
map.put("age", "20");
map.put("gender", "男");
jedis.hmset("person:" + jedis.incr("index"), map);
}
哈希 hash 是一个 string 类型的 field 和 value 的映射表,hash 特适合用于存储对象
注意:key 只有一个
上表中就可是使用 hash 类型来存储 order:1 name 值 createtime 值 uid 值
order:1:key 分布式 模块名称:项目名称:表:主键
oid 1 name 衣服订单 createtime 2020-02-11 uid 1 :value
value 由多组 field,value
hmset order:1 oid 1 name 衣服订单 createtime 2020-02-11 uid 1
常用命令
命令 hset key field value
设值:hset order:2 oid 1 //成功返回1,失败返回0
取值:hget order:2 oid //返回 1
取出所有值:hgetall use1:1 ***
删值:hdel user:1 age … //返回删除的个数
计算个数:hset user:1 name james; hset user:1 age 23;
hlen user:1 //返回2,user:1有两个属性值
批量设值:hmset user:2 name james age 23 sex boy //返回OK ***
批量取值:hmget user:2 name age sex //返回三行:james 23 boy ***
判断field是否存在:hexists user:2 name //若存在返回1,不存在返回0
获取所有field: hkeys user:2 // 返回name age sex三个field
获取user:2所有value:hvals user:2 // 返回james 23 boy
获取user:2所有field与value:hgetall user:2 //name age sex james 23 boy值
增加1:hincrby user:2 age 1 //age+1,给对象某个属性值增加指定量
hincrbyfloat user:2 age 2 //浮点型加2
hetall
keys patterns //匹配所有满足条件的key
string 类型和hash类型对比
(1)string类型
优点:简单直观,每个键对应一个值,用string类型存储单个变量
缺点:键数过多,占用内存多,用户信息过于分散,不用于生产环境
(2) hash类型
优点:简单直观,使用合理可减少内存空间消耗 value最大存储512M
缺点:要控制ziplist与hashtable两种编码转换,且hashtable会消耗更多内serialize(userInfo);
public class Person {
private String name;
private String age;
private String gender;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
", gender='" + gender + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
//把对象存储到Redis中
@Test
public void test03() {
jedis.select(1);
Person person = new Person();
person.setName("小梅");
person.setAge(18 + "");
person.setGender("女");
Map map = new HashMap<>();
//对象==>Map
BeanUtil.beanToMap(person, map, false, true);
Map data = RedisUtil.mapToMap(map);
jedis.hmset("person:" + jedis.incr("index"), data);
}
@Test
public void test04() {
Person person1 = new Person();
person1.setName("小梅");
person1.setAge(18 + "");
person1.setGender("女");
Person person2 = new Person();
person2.setName("小红");
person2.setAge(30 + "");
person2.setGender("女");
List personList = new ArrayList();
personList.add(person1);
personList.add(person2);
RedisUtil.dbToRedis(personList, jedis, 5, "person:");
}
@Test
public void test05() {
jedis.select(5);
Set keys = jedis.keys("person:*");
List personList = new ArrayList<>();
for (String key : keys) {
Map map = jedis.hgetAll(key);
Person person = BeanUtil.mapToBean(map, Person.class, false, new CopyOptions().ignoreNullValue());
personList.add(person);
}
System.out.println(personList);
}
@Test
public void test06() {
List personList = RedisUtil.redisToJava(Person.class, jedis, 5, "per*");
System.out.println(personList);
}
用来存储多个有序的字符串,一个列表最多可存2的32次方减1个元素 LinkedList
使用场景:消息队列、排队
因为有序,可以通过索引下标获取元素或某个范围内元素列表,列表元素可以重复
常用命令
(1)添加命令:
rpush james c b a //从右向左插入cba, 返回值3 ***
lrange james 0 -1 //从左到右获取列表所有元素 返回 c b a 0 -1:遍历所有元素 ***
lpush key c b a //从左向右插入cba
linsert james before b teacher //在b之前插入teacher, after为之后,使用lrange james 0 -1 查看:c teacher b a
(2)查找命令:
lrange key start end //索引下标特点:从左到右为0到N-1 ***
lindex james -1 //返回最右末尾a,-2返回b
llen james //返回当前列表长度
lpop james //把最左边的第一个元素c删除
rpop james //把最右边的元素a删除
用户标签,社交,查询有共同兴趣爱好的人,智能推荐,保存多元素,与列表不一样的是不允许有重复元素,且集合是无序,一个集合最多可存2的32次方减1个元素,除了支持增删改查,还支持集合交集、并集、差集;
常用命令
exists user //检查user键值是否存在
sadd user a b c //向user插入3个元素,返回3 ***
sadd user a b //若再加入相同的元素,则重复无效,返回0
smembers user //获取user的所有元素,返回结果无序 ***
sismember user a:判断是否存在某个元素
srandmember user:随机抽取元素 抽奖
sdiff key1 key2...:求差集
srem user a //返回1,删除a元素:rem:remove
scard user //返回2,计算元素个数
sinter :求交集 ***
使用场景
标签,社交,查询有共同兴趣爱好的人,智能推荐
(1)给用户添加标签
sadd user:1:fav travel eating swiming
sadd user:2:fav travel eating sleep
(2)或给标签添加用户
sadd basball:fav user:1 user:2 user:3
(3)计算出共同感兴趣的人
sinter user:1:fav user:2:fav
有序:里面有一个列值存放的是数值,确实也可以通过索引取值
常用于排行榜,如视频网站需要对用户上传视频做排行榜,或点赞数与集合有联系,不能有重复的成员
LIST和SET对比
数据结构 | 是否允许元素重复 | 是否有序 | 有序实现方式 | 应用场景 |
---|---|---|---|---|
列表:list | 是 | 是 | 索引下标 | 时间轴,消息队列 |
集合:set | 否 | 否 | 无 | 标签,社交、投票、抽奖 |
有序集合:zset | 否 | 是 | 分值:score | 排行榜,点赞数 |
常用命令
(1)指令:
zadd key score member [score member......] ***
zadd user:zan 200 james //james的点赞数1, 返回操作成功的条数1
zadd user:zan 200 james 120 mike 100 lee // 返回3
zadd test:1 nx 100 james //键test:1必须不存在,主用于添加
zadd test:1 xx incr 200 james //键test:1必须存在,主用于修改,此时为300
zadd test:1 xx incr -299 james //返回操作结果1,300-299=1
zrange test:1 0 -1 withscores //查看点赞(分数)与成员名
zcard test:1 //计算成员个数, 返回1
zcount key min max:在指定区间的个数 min、max:对应的score的值
zrank key member:索引
(2)排名场景:
zadd article:1 10 zhangsan 1 lisi 100 wangwu //先插入数据
zrange article:1 0 -1 //查看正序成员
zrange article:1 0 -1 withscores //查看正序分数与成员
zrevrange article:1 0 -1 withscores //查看逆序分数与成员
zrank user:3 james //返回名次:第3名返回2,从0开始到2,共3名
zrevrank user:3 james //返回0, 反排序,点赞数越高,排名越前
rev:reverse
zscore videos:news lisi //获取分值
应用场景
zadd videos:news 1000 zhangsan 500 lisi 5 wangwu
//zhangsan:1000个赞,lisi:500个赞,wangwu:5个赞
zrevrange videos:news 0 -1 withscores //查看点赞数和成员zscore videos:news lisi //查看 lisi 点赞数
zincrby videos:news 1 lisi // lisi 点赞数 + 1
zincrby videos:news 50 wangwu // wangwu 点赞数 + 50
zrevrange videos:news 0 -1 withscores //查看点赞数和成员点赞数 zadd user:1:20180106 3 mike //mike获得3个赞
再获一赞 zincrby user:1:20180106 1 mike //在3的基础上加1
用户作弊,将用户从排行榜删掉 zrem user:1:20180106 mike
展示赞数最多的5个用户 zrevrange user:1:20180106 0 4
查看用户赞数与排名 zscore user:1:20180106 mike zrank user:1:20180106 mike