在redis中用的最多的就是hash和string类型。
问题
假设有User对象以JSON序列化的形式存储到redis中,
User对象有id、username、password、age、name等属性,
存储的过程如下:
保存、更新:
User对象->json(string)->redis
如果在业务上只是更新age属性,其他的属性并不做更新应该怎么做呢?
Redis数据类型之散列类型hash
散列类型存储了字段(field)和字段值的映射,但字段值只能是字符串,不支持其他类型,
也就是说,散列类型不能嵌套其他的数据类型。
一个散列类型可以包含最多232-1个字段。
hset / hget
赋值和取值
HSET命令不区分插入和更新操作,
当执行插入操作时HSET命令返回1,当执行更新操作时返回0。
HSET key field value HGET key field HMSET key field value [field value…] HMGET key field value [field value…] HGETALL key
127.0.0.1:6379> hset user username chenchen #插入 (integer) 1 127.0.0.1:6379> hget user username #取值 "chenchen" 127.0.0.1:6379> hset user username chen #更新 (integer) 0 127.0.0.1:6379> keys user 1) "user" 127.0.0.1:6379> hgetall user #一次取key的所有字段及字段值 1) "username" 2) "chen" 127.0.0.1:6379> 127.0.0.1:6379> hset user age 30 (integer) 1 127.0.0.1:6379> hgetall user 1) "username" 2) "chen" 3) "age" 4) "30" 127.0.0.1:6379>
hincrby(自增)
HINCRBY和INCR区别:HINCRBY如果没有KEY, 则自动创建KEY然后赋值。
而INCR只能添加不能判断。
127.0.0.1:6379> hdecrby article total 1
127.0.0.1:6379> hincrby article total -1 #没有hdecrby自减命令
(integer) 1
hmset / hmget
HMSET和HMGET设置和获取对象属性
注意:上面HMGET字段顺序可以自行定义
127.0.0.1:6379> hmset person username tony age 18 OK 127.0.0.1:6379> hmget person age username 1) "18" 2) "tony" 127.0.0.1:6379> hgetall person 1) "username" 2) "tony" 3) "age" 4) "18" 127.0.0.1:6379>
hexists
属性是否存在
127.0.0.1:6379> hexists killer (error) ERR wrong number of arguments for 'hexists' command 127.0.0.1:6379> hexists killer a (integer) 0 127.0.0.1:6379> hexists user username (integer) 1 127.0.0.1:6379> hexists person age (integer) 1 127.0.0.1:6379>
hdel
删除属性
127.0.0.1:6379> hdel user age (integer) 1 127.0.0.1:6379> hgetall user 1) "username" 2) "chen" 127.0.0.1:6379> hgetall person 1) "username" 2) "tony" 3) "age" 4) "18" 127.0.0.1:6379>
hkeys / hvals
只获取字段名HKEYS或字段值HVALS
127.0.0.1:6379> hkeys person 1) "username" 2) "age" 127.0.0.1:6379> hvals person 1) "tony" 2) "18"
hlen
元素个数
127.0.0.1:6379> hlen user (integer) 1 127.0.0.1:6379> hlen person (integer) 2 127.0.0.1:6379>
Jredis示例
注意:key值的大小写是区分的。
public class JedisPoolDemoCMD { public static void main(String[] args) { // 构建连接池配置信息 JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); // 设置最大连接数 jedisPoolConfig.setMaxTotal(50); // 构建连接池 JedisPool jedisPool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379); // 从连接池中获取连接 Jedis jedis = jedisPool.getResource(); jedis.hset("USER_1", "username", "zhangsan"); jedis.hset("USER_1", "password", "123456"); Map<String, String> val = jedis.hgetAll("USER_1"); for (Map.Entry<String, String> entry : val.entrySet()) { System.out.println(entry.getKey() + " " + entry.getValue()); } // 将连接还回到连接池中 jedisPool.returnResource(jedis); // 释放连接池 jedisPool.close(); } } Redis中测试: 127.0.0.1:6379> hgetall USER_1 1) "username" 2) "zhangsan" 3) "password" 4) "123456" 127.0.0.1:6379> hgetall user_1 (empty list or set) 127.0.0.1:6379>