选项1
如果您正在寻找一种与实现语言无关的方式,即期望在使用不同编程语言编写的系统的不同部分中获得相同的操作和结果,则建议采用@Not_a_Golfer's recommendation。
选项2
但是,如果您只使用Java,并且尚未运行Redis 4.0,则建议使用Redisson作为客户端库,以使此工作更加轻松。
免责声明:我是Redisson项目的成员,我的观点具有偏见。这篇文章也是希望能够传达给其他处于这种情况的人。
Redisson是一个客户端Java库,让您将Redis作为内存数据网格操作。它自然支持多维复杂对象。
Redisson使用标准Java接口提供Redis数据类型,例如Redis哈希提供了java.util.Map
和java.util.concurrent.ConcurrentMap
,因此在您的情况下,使用方法会非常简单:
User user01 = new User();
user01.setUsername("ally");
user01.setEmail("all@gmail.com");
User user02 = new User();
user02.setUsername("user2");
user02.setEmail("...");
Map<String, User> users = redisson.getMap("users");
users.put("user01", user01);
users.put("user02", user02);
Truck truck01 = new Truck();
truck01.setRegNo("azn102");
truck01.setMake("subaru");
Truck truck02 = new Truck();
truck02.setRegNo("kcaher3");
truck02.setMake("...");
Map<String, Truck> trucks = redisson.getMap("trucks");
trucks.put("truck01", truck01);
trucks.put("truck02", truck02);
获取您的数据同样容易
User user01 = users.get("user01");
Truck truck02 = trucks.get("truck02");
在Redis中,你会得到两个哈希对象,一个称为“users”,另一个称为“trucks”,你会发现JSON字符串存储在这些哈希对象的指定字段名中。
现在,你可能会争辩说这并不是真正的嵌套对象,这只是一种数据序列化。
好吧,让我们让例子更加复杂,以看到区别:如果你想保留所有开过特定卡车的用户列表,你也可能想轻松地找出哪个卡车当前正在被用户驾驶。
我会说这些都是相当典型的业务用例。
这确实增加了数据结构的维度和复杂性。通常你需要将它们分成不同的部分:
- 你需要将“Truck”和“User”映射到不同的哈希对象中,以避免数据重复和一致性问题;
- 你还需要管理每辆卡车的单独列表,以存储使用日志。
在Redisson中,这些类型的任务处理更自然,且无需考虑上述问题。
你可以像在Java中一样简单地做到这一点:
1.使用@REntity注释您的“User”类和“Truck”类,并选择一个标识符生成器或指定您自己,这可以是字段的值。
2.向“Truck”类添加List字段(usageLog)。
3.向“User”类添加Truck字段(currentlyDriving)。
这就是你需要的全部。因此,使用方式不比在Java中通常做的多。
RLiveObjectService service = redisson.getLiveObjectService();
service.registerClass(User.class);
service.registerClass(Truck.class);
Truck truck01 = new Truck();
truck01.setRegNo("azn102");
truck01.setMake("subaru");
service.persist(truck01);
User user02 = new User();
user02.setUsername("user2");
user02.setEmail("...");
service.persist(user02);
truck01.getUsageLog().add(user02);
user02.setCurrentlyDriving(truck01);
Map<String, Truck> trucks = redisson.getMap("trucks");
trucks.put("truck01", truck01);
Map<String, User> users = redisson.getMap("users");
users.put("user02", user02);
因此,最终得到的是每个记录都存储在Redis和哈希中,每个卡车记录都保留了使用它的用户记录的独立列表,用户记录现在包含了他/她当前正在驾驶的卡车信息。所有这些都是使用对象引用而不是复制域记录来完成的。
正如您所看到的,Redisson提供了一个解决方案,可以在整个过程中解决所有问题。
有关Redisson如何通过对象哈希映射和对象引用处理Redis中的多维复杂对象的更多信息,请参考: