`

征服 Redis + Jedis + Spring (二)—— 哈希表操作(HMGET HMSET)

阅读更多

不得不说,用哈希操作来存对象,有点自讨苦吃!

不过,既然吃了苦,也做个记录,也许以后API升级后,能好用些呢?!

或许,是我的理解不对,没有真正的理解哈希表。

 

相关链接:

征服 Redis

征服 Redis + Jedis

征服 Redis + Jedis + Spring (一)—— 配置&常规操作(GET SET DEL)

征服 Redis + Jedis + Spring (二)—— 哈希表操作(HMGET HMSET)

征服 Redis + Jedis + Spring (三)—— 列表操作

 

一、预期

接上一篇,扩充User属性:

 

public class User implements Serializable {
	private static final long serialVersionUID = -1267719235225203410L;

	private String uid;

	private String address;

	private String mobile;

	private String postCode;
}

 我期望的是: 

 

 

redis 127.0.0.1:6379> hmget uc.user.info.uid.u123456 address mobile postCode
1) "\xe4\xb8\x8a\xe6\xb5\xb7"
2) "13800138000"
3) "100859"

 

 

几乎就是一个对象了! 

但是,接下来的代码实现,让我彻底崩溃了!

 

二、代码实现

1.保存——HMSET

 

	@Override
	public void save(final User user) {
		redisTemplate.execute(new RedisCallback<Object>() {
			@Override
			public Object doInRedis(RedisConnection connection)
					throws DataAccessException {
				byte[] key = redisTemplate.getStringSerializer().serialize(
						"uc.user.info.uid." + user.getUid());
				BoundHashOperations<Serializable, byte[], byte[]> boundHashOperations = redisTemplate
						.boundHashOps(key);
				boundHashOperations.put(redisTemplate.getStringSerializer()
						.serialize("mobile"), redisTemplate
						.getStringSerializer().serialize(user.getMobile()));
				boundHashOperations.put(redisTemplate.getStringSerializer()
						.serialize("address"), redisTemplate
						.getStringSerializer().serialize(user.getAddress()));
				boundHashOperations.put(redisTemplate.getStringSerializer()
						.serialize("postCode"), redisTemplate
						.getStringSerializer().serialize(user.getPostCode()));
				connection.hMSet(key, boundHashOperations.entries());
				return null;
			}
		});
	}

 

 

这里用到:

 

BoundHashOperations<Serializable, byte[], byte[]> boundHashOperations = redisTemplate.boundHashOps(key);
boundHashOperations.put(redisTemplate.getStringSerializer().serialize("mobile"), redisTemplate.getStringSerializer().serialize(user.getMobile()));

 看着就有点肿。。。Map封装完以后,用HMSET命令:

 

connection.hMSet(key, boundHashOperations.entries());

 这时候就完成了哈希表的保存操作,可以在控制台看到相应的数据了。

 

redis 127.0.0.1:6379> hmget uc.user.info.uid.u123456 address mobile postCode
1) "\xe4\xb8\x8a\xe6\xb5\xb7"
2) "13800138000"
3) "100859"

 

2.获取——HMGET

这一刻,我彻底崩溃了!取出来的值是个List,还得根据取得顺序,逐个反序列化,得到内容。

 

	@Override
	public User read(final String uid) {
		return redisTemplate.execute(new RedisCallback<User>() {
			@Override
			public User doInRedis(RedisConnection connection)
					throws DataAccessException {
				byte[] key = redisTemplate.getStringSerializer().serialize(
						"uc.user.info.uid." + uid);
				if (connection.exists(key)) {
					List<byte[]> value = connection.hMGet(
							key,
							redisTemplate.getStringSerializer().serialize(
									"address"),
							redisTemplate.getStringSerializer().serialize(
									"mobile"), redisTemplate
									.getStringSerializer()
									.serialize("postCode"));
					User user = new User();
					String address = redisTemplate.getStringSerializer()
							.deserialize(value.get(0));
					user.setAddress(address);
					String mobile = redisTemplate.getStringSerializer()
							.deserialize(value.get(1));
					user.setMobile(mobile);
					String postCode = redisTemplate.getStringSerializer()
							.deserialize(value.get(2));
					user.setPostCode(postCode);
					user.setUid(uid);

					return user;
				}
				return null;
			}
		});
	}

 这个实现,跟Redis的命令几乎一模一样,指定Key,指定field,获取其值。

 

List<byte[]> value = connection.hMGet(key,redisTemplate.getStringSerializer().serialize("address"),
redisTemplate.getStringSerializer().serialize("mobile"), 
redisTemplate.getStringSerializer().serialize("postCode"));

 我绝对相信,要么是我用的过于肤浅,低估了Spring的封装能力。或者,我该直接Json!等等,这不是MongoDB干的事情吗?!

PS:这两篇博客里操作的数据类型,只能是String类型,还没搞定除此以外任何类型。吾将上下而求索~~~

上述操作也许你吐了,接下来的代码,就再吐一次吧!

封装对象的时候,一定要记得次序。。。。这绝对不是一个优质代码的实现风格!

 

User user = new User();
String address = redisTemplate.getStringSerializer().deserialize(value.get(0));
user.setAddress(address);
String mobile = redisTemplate.getStringSerializer().deserialize(value.get(1));
user.setMobile(mobile);
String postCode = redisTemplate.getStringSerializer().deserialize(value.get(2));
user.setPostCode(postCode);

 好吧!苦逼的事情,就此结束。目标Json支持!

 

 

相关链接:

征服 Redis

征服 Redis + Jedis

征服 Redis + Jedis + Spring (一)—— 配置&常规操作(GET SET DEL)

征服 Redis + Jedis + Spring (二)—— 哈希表操作(HMGET HMSET)

征服 Redis + Jedis + Spring (三)—— 列表操作

6
5
分享到:
评论
16 楼 我要骑老虎 2015-10-27  
cai576416582 写道
  貌似我看到同事把整个对象转换成byte之后 再一次性序列化 在存取 这样方便

。。。我就是这样实现redis的用户登录信息同步的
15 楼 cai576416582 2014-07-27  
  貌似我看到同事把整个对象转换成byte之后 再一次性序列化 在存取 这样方便
14 楼 ydm305365 2013-08-30  
楼主直接用HashMapper,toHash(Object)

boundHashOperations.putAll(hashMapper.toHash(Object));

不就可以了,
13 楼 markone 2013-07-07  
操作hash用hgetAll,hmset, hmget还行。。。代码没这么臃肿
12 楼 gkyh 2013-06-09  
楼主我怎么报错找不到原因:

java.lang.ClassCastException: [B cannot be cast to java.lang.String
at org.springframework.data.redis.serializer.StringRedisSerializer.serialize(StringRedisSerializer.java:32)
at org.springframework.data.redis.core.AbstractOperations.rawKey(AbstractOperations.java:94)
at org.springframework.data.redis.core.DefaultHashOperations.put(DefaultHashOperations.java:159)
at org.springframework.data.redis.core.DefaultBoundHashOperations.put(DefaultBoundHashOperations.java:92)

boundHashOperations.put(redisTemplate.getStringSerializer() 
                    .serialize("mobile"), redisTemplate 
                    .getStringSerializer().serialize(user.getMobile()));

11 楼 superscorpio 2013-06-09  
之前尝试过,太麻烦了,果断放弃了。跟MongoTemplate差远了。
10 楼 指隙阳光12138 2013-04-02  
哎,用Jedis存储对象这块的确好痛苦啊。之前有个JOhm,是用反射做的,能用倒是能用,不过貌似根本不支持ShardedJedisPool,更坑爹的是貌似用反射性能好低的...

都说redis单点性能比memcached的要高,可是如果是用来存储对象的话,我发现貌似还是MemcachedClient要快==
9 楼 snowolf 2013-03-16  
cpjsjxy 写道
你这模式真心没我们现在用的模式好!
说说你现在的,后面那篇我想才是Spring想要真正去使用的
8 楼 cpjsjxy 2013-03-16  
你这模式真心没我们现在用的模式好!
7 楼 命中注定1314 2013-03-09  
snowolf 写道
命中注定1314 写道
楼主,经过试验发现不能对Hash类型做删除操作,执行了没有效果。

我那段没有开放的代码,被你测试了?!

还是可以做删除那些,api没弄对, 今天封装了个简单的通用的CRUD类。
6 楼 snowolf 2013-03-06  
命中注定1314 写道
楼主,经过试验发现不能对Hash类型做删除操作,执行了没有效果。

我那段没有开放的代码,被你测试了?!
5 楼 命中注定1314 2013-03-06  
楼主,经过试验发现不能对Hash类型做删除操作,执行了没有效果。
4 楼 snowolf 2013-03-05  
snowolf 写道
dts228 写道
Hi,我今天也瞅了下,发现spring自己封装了个ValueOperations来操作redis,比你这个要方便的呢。可以使用tmpl.opsForValue(),tmpl.opsForList()等来获取不通的op操作对象或者集合,,确实方便哈。

o ?抽空我也看看~

今天看了看,确实方便,未能深入研究。感谢提点!
3 楼 snowolf 2012-12-25  
dts228 写道
Hi,我今天也瞅了下,发现spring自己封装了个ValueOperations来操作redis,比你这个要方便的呢。可以使用tmpl.opsForValue(),tmpl.opsForList()等来获取不通的op操作对象或者集合,,确实方便哈。

o ?抽空我也看看~
2 楼 dts228 2012-12-24  
Hi,我今天也瞅了下,发现spring自己封装了个ValueOperations来操作redis,比你这个要方便的呢。可以使用tmpl.opsForValue(),tmpl.opsForList()等来获取不通的op操作对象或者集合,,确实方便哈。
1 楼 kuro_0505 2012-09-15  
确实很痛苦,这样子太操蛋了~看看有没有好点方法~

相关推荐

    spring boot redis-jedis

    除了基本的键值操作外,Jedis还支持多种数据结构的操作,如集合(Set)、列表(List)、哈希表(Hash)和有序集合(Sorted Set)。例如,如果我们需要存储一个用户的购物车商品列表,可以使用List: ```java public...

    redis+spring+maven

    4. **RedisTemplate方法**: 你可以直接调用`RedisTemplate`的方法进行键值对的操作,如`opsForValue().set(key, value)`用于设置字符串,`opsForHash().put(hashKey, field, value)`用于哈希表操作。 5. **Jedis与...

    BAT大厂高频面试题:Redis+JVM+微服务+并发+Spring+MyBatis.docx

    根据给定文件的信息,我们可以提炼出以下几个主要技术领域内的知识点:Redis、JVM、微服务、并发编程、Spring以及MyBatis。 ### Redis #### 1. 什么是 Redis? Redis (REmote DIctionary Server) 是一种开源的键值...

    Spring mvc整合redis实例(redis连接池)

    例如,获取哈希表中的值: ```java public Map, Object&gt; getHashValues(String hashKey) { return redisTemplate.opsForHash().entries(hashKey); } ``` 此外,为了进一步简化代码,可以自定义一个服务类,将常用...

    学废SpringBoot+Redis+Lua=王炸(值得珍藏)

    在Spring Boot中,可以使用`Jedis`或`Lettuce`库来连接和操作Redis。通过这些库,开发者可以方便地调用Lua脚本,利用Redis的`EVAL`命令执行预定义的业务逻辑。例如,可以编写一个Lua脚本来实现事务操作,确保数据的...

    redis集群以及Spring-data-redis操作集群

    3. **操作示例**:如`opsForValue()`、`opsForHash()`等方法分别对应键值对操作、哈希表操作等。 总结来说,Redis集群是提升系统性能和可用性的关键,而Spring-data-redis则是简化了在Java应用中使用Redis(包括...

    Redis使用lettuce和jedis.pdf

    Redis是一种开源的高性能键值存储数据库,支持多种类型的数据结构,包括字符串、哈希表、列表、集合、有序集合等。它广泛应用于缓存、消息队列、计数器和实时分析等多种场景。在Java应用程序中,常用的操作Redis的...

    SpringMvc+redis+activeMq实现消息发布订阅(测试通过)

    它支持多种数据结构如字符串、哈希表、列表、集合和有序集合,这使得Redis在处理复杂的数据操作时非常灵活。在本案例中,Redis可以作为消息的临时存储,确保消息的可靠传输。 ActiveMQ是Apache软件基金会开发的一款...

    详解SSH框架和Redis的整合

    5. **Redis操作**:通过Spring的`JedisTemplate`或`StringRedisTemplate`进行Redis的数据操作,如设置、获取、删除键值对,以及列表、集合、哈希表等数据结构的操作。 6. **缓存策略**:设计合适的缓存策略,比如...

    jedis操作redis工具类,使用该工具类无需配置spring

    总的来说,使用Jedis操作Redis的工具类可以极大地方便Java开发者在项目中集成Redis,提高开发效率,同时避免直接操作连接可能导致的资源泄露等问题。只需根据实际需求调用工具类的方法,即可实现各种Redis数据操作,...

    redis jar 兼容版

    Jedis.jar是Java语言的一个Redis客户端,它提供了丰富的API以支持各种Redis命令,包括字符串、哈希表、列表、集合、有序集合的操作,以及事务、发布/订阅、管道等功能。Jedis的设计简洁且高效,可以满足大部分基于...

    springboot_SpringDataRedis_redis.zip

    此外,Spring Data Redis还提供了其他的Ops,如`opsForHash()`用于操作哈希表,`opsForList()`处理列表数据,`opsForSet()`管理集合,以及`opsForZSet()`处理有序集合。这些Ops允许我们以面向对象的方式与Redis交互...

    spring redis

    2. **HashOperations**:处理哈希表,支持获取、设置、删除单个字段或整个哈希。 3. **ListOperations**:操作列表,可以添加、获取、删除元素,以及实现LIFO/FIFO队列。 4. **SetOperations**:管理集合,支持添加...

    redis与spring的整合

    4. **Map**:使用opsForHash()处理Map,支持添加、删除、获取单个字段、遍历整个哈希表等。例如: ```java HashOperations, String, String&gt; hashOps = template.opsForHash(); hashOps.put("myMap", "field1", ...

    redis 安装+demo源码

    继续深入学习,你还可以探索Redis的更多高级特性,如发布订阅、哈希表、有序集合、HyperLogLog等,以及如何利用它们解决实际问题。记住,实践是掌握技术的关键,尝试编写自己的应用并不断优化,你将成为Redis的专家...

    redis整合Spring 需要jar包

    例如,你可以使用Jedis进行字符串、哈希表、列表、集合和有序集合的操作,以及发布订阅、事务处理等。Jedis-2.9.0是该库的一个稳定版本,包含了许多优化和修复,能够很好地支持Redis的各种功能。 另一个关键的jar包...

    Spring-data-redis使用指南

    - **丰富的特性**: 支持字符串、哈希表、列表、集合等多种数据类型的操作,并提供了事务管理、消息订阅发布等功能。 - **高性能**: 内置了多种连接池机制,如 Jedis 和 Lettuce,确保高并发场景下的稳定性和性能。 -...

    Spring Redis操作手册

    ### Spring Redis操作手册知识点解析 #### 一、文档概述与目的 - **文档基本信息:** - **文档名称:** Spring-data-redis使用手册 - **文档编号:** 2012-02-14 - **作者:** 黄承开 - **最后发布时间:** ...

Global site tag (gtag.js) - Google Analytics