如何在Java中实现规范化映射?

Bjö*_*lex 10 java orm weak-references canonicalization

我目前正在编写自己的小ORM,并发现自己面临着创建规范化映射的任务,以防止从数据库中多次加载同一个实体.

我目前的做法是使用a HashMap<Object, WeakReference<Object>>.密钥是映射的数据库实体的主键(ArrayList<Object>如果它是复合键),则值为WeakReference<Object>.

我的主要问题是如何清理地图?当一个对象不再使用时,地图中的弱引用将会出现null,我只会在下一次查找时发现这一点(或者,如果我不再查看该对象,则永远不会发现).ReferenceQueue当它们被清除时,我可以使弱引用注册为a ,然后每次查看时检查该队列.清除的引用不会给我任何关于哪个对象被清除的提示,所以我想我必须子类WeakReference将该键存储在地图中,所以我可以在清除引用后将其删除.

这是要走的路,还是有更简单的方法来实现它?

Pau*_*ora 14

我建议在r10中使用Guava的MapMakerCacheBuilder.

它们允许自动*基于时间和大小的驱逐,以及支持弱键或值.(即将到来的CacheBuilder承诺将专门针对此类用例量身定制.)

所以你可以初始化你的地图:

ConcurrentMap<Key, Object> cache = new MapMaker()
        .weakValues()
        .makeMap();
Run Code Online (Sandbox Code Playgroud)

并且直接的好处是当一个值被垃圾收集时,整个条目将被删除.此外,您可以使用计算地图:

ConcurrentMap<Key, Object> cache = new MapMaker()
        .weakValues()
        .makeComputingMap(loadFunction);
Run Code Online (Sandbox Code Playgroud)

在哪里loadFunctionFunction<Key, Object>从数据库加载对象.这样做的好处是映射将处理特定对象的并发请求,确保只调用一次查询.此外,请求代码只需要调用get(),并且始终可以期望从缓存或数据库返回对象.

这些例子正在使用MapMaker- 我还没有玩得开心的乐趣CacheBuilder.

有关更多示例,请使用guava查看我的理想缓存.该文章讨论了如何将基于时间的驱逐与规范化相结合.

  • 我最初想要添加这个库时犹豫不决,但是现在我做了,我想知道为什么我之前没有这样做.谢谢你的回答! (2认同)