选项 1
我认为如果您正在寻找一种独立于实现语言的方式,即在使用不同编程语言编写的系统的不同部分中期望相同的操作和结果,那么@Not_a_Golfer 's recommendation 最适合您的情况。
选项 2
但是,如果您碰巧只使用 Java 并且尚未运行 Redis 4.0,我建议您使用 Redisson 作为您的客户端库,以使您自己更轻松地完成这项工作。
免责声明,我是Redisson 项目的成员,我在下面的观点是有偏见的。写这篇文章也是希望能传达给处于这种确切情况的其他人。
Redisson 是一个客户端 Java 库,可让您将 Redis 作为内存数据网格进行操作。自然支持多维复杂对象。
Redisson 为 Redis 数据类型提供标准 Java 接口,即 Redis hash 提供为 java.util.Map 和 java.util.concurrent.ConcurrentMap,因此在您的情况下,用法很简单:
//lets imagine you have a builder that creates users
User user01 = new User();
user01.setUsername("ally");
user01.setEmail("all@gmail.com");
User user02 = new User();
user02.setUsername("user2");
user02.setEmail("...");
//You get a Redis hash handler that works as a standard Java map
Map<String, User> users = redisson.getMap("users");
//This is how you put your data in Redis
//Redisson serialize the data into JSON format by default
users.put("user01", user01);
users.put("user02", user02);
//the same works for trucks
Truck truck01 = new Truck();
truck01.setRegNo("azn102");
truck01.setMake("subaru");
Truck truck02 = new Truck();
truck02.setRegNo("kcaher3");
truck02.setMake("...");
//The same as above
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 字符串针对这些哈希对象中的指定字段名称进行存储。
现在,您可能会争辩说这并不是一个真正的嵌套对象,这只是一个数据序列化。
好的,让这个例子稍微复杂一点,看看有什么区别:如果你想保留所有驾驶过特定卡车的用户的列表,你可能还想轻松找出用户是哪辆卡车目前正在开车。
我会说这些是相当典型的业务用例。
这确实为数据结构增加了更多维度和复杂性。通常,您必须将它们分成不同的部分:
在 Redisson 中,这些类型的任务处理得更加自然,无需考虑上述担忧。
您可以像往常一样在 Java 中像这样简单地做:
使用@REntity 注释注释您的User 类和Truck 类,并选择您自己的标识符生成器或说明符,这可以是字段的值。
将 List 字段 (usageLog) 添加到 Truck 类。
将 Truck 字段(currentDriving)添加到 User 类。
这就是你所需要的。所以用法并不比你通常在 Java 中做的多:
//prepare the service and register your class.
RLiveObjectService service = redisson.getLiveObjectService();
service.registerClass(User.class);
service.registerClass(Truck.class);
Truck truck01 = new Truck();
truck01.setRegNo("azn102");
truck01.setMake("subaru");
//stores this record as a Redis hash
service.persist(truck01);
User user02 = new User();
user02.setUsername("user2");
user02.setEmail("...");
//stores this record as a Redis hash
service.persist(user02);
//assuming you have invoked setUsageLog elsewhere.
truck01.getUsageLog().add(user02);
user02.setCurrentlyDriving(truck01);
//under normal circumstance keeping a Redis hash registry is not necessary.
//the service object can be used for this type of look up.
//this is only for demonstration.
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中的多维复杂对象: