Groovy:MultiValueMap,地图为键

时间:2011-08-18 00:57:36

标签: java data-structures groovy apache-commons multivalue

Heres是我正在考虑的事情,我想知道你是否认为这是一个好主意。

我从数据库中检索了一堆行,在groovy中给我一个列表列表,如:

[
  [ 'Dog', 'M', 'Mutt', 'Sammy' ],
  [ 'Cat', 'F', 'Siamese', 'Pat' ],
  [ 'Dog', 'M', 'Husky', 'Taco' ],
  ...
]

不是我的真实数据集,但你明白了。

由于我会非常频繁地提取这些数据并在UI中显示之前对其进行一些分析,我想将它存储在由groovy贴图(即LinkedHashMaps)键入的MultiValueMap中,因此我可以检索我需要它的一点一滴,而不是每次都去DB。它是来自几个表的数据子集的缓存(比上面的动物数据更复杂)。

我可以像这样使用它:

animals.get([species:'Dog', gender:'M'])

返回:

[['Sammy', 'Mutt'], ['Taco', 'Husky'] ]

我想我有一些想法如何实现它,所以我不是真的在寻找它(尽管如果你有一个新颖的建议请分享)。我主要是想找个人告诉我这个或者由于某些原因不起作用,或者听起来不错,或者它不会扩展等等。或者可能有一些更简单的方法来获得类似的功能。还有一个考虑因素:整个数据集有时可能很大,例如,几十条记录。如果不是这样,除了每次击中数据库之外,有什么好处理它?<​​/ p>

我意识到有许多关键/价值缓存解决方案,但我认为我不需要做任何如此繁重的工作。它只是一个使用率很低的小型webapp,主要是我正在构建它的公司内部。

2 个答案:

答案 0 :(得分:2)

如果您使用的值的子集是静态/确定性的,我只需将其转换为字符串并将其用作地图中的键。因此,我使用animals.get([species:'Dog', gender:'M'])而不是animals.get('species:Dog:gender:M')

我知道你说你认为键值存储太重了,但这也是Redis的完美用例,可以natively store things like hash maps

您所谈论的存储缓存类型正是我们在工作中使用它的方式,而且非常棒。它非常快,并且可以在所有正在运行的进程中使用,而无需单个映射或非常大的映射的多个副本。缓存失效也是您需要考虑的,redis有助于解决。

您可以使用grails-redis plugin来记忆您的数据库调用,以便它首先自动检查redis以查看它是否在缓存中,如果不是,它会查询数据库并将其粘贴到缓存中归还它。有关详细信息/示例,请参阅docs on github

return redisService.memoizeHash('species:Dog:gender:M') {
    // database call that returns object, then you turn that into hash
    Dog d = Dog.findBy...
    [species: d.species, gender: d.gender, breed: d.breed, name: d.name, ...]
}

这样,只有当Redis尚未在缓存中拥有它时,它才会查询数据库。在高速缓存未命中时,它将返回值保存在指定键的redis中。

(免责声明,我是grails-redis plugin的作者,所以我有一些偏见)

答案 1 :(得分:0)

使用可变映射作为键是一个非常糟糕的主意,因为如果键发生更改,则无法找到它。