2

我想在 JavaEE 应用程序服务器的 Java 堆上缓存如下 DB 表中的内容。

| group   | key     | value                                  |
| ------- | ------- | -------------------------------------- |
| CHAR(3) | CHAR(5) | VARCHAR(256)                           |
| ------- | ------- | -------------------------------------- |
| 001     | 0       | male                                   |
| 001     | 1       | female                                 |
| 001     | 9       | other                                  |
| 002     | 004     | Afghanistan                            |
| 002     | 008     | Albania                                |
| 002     | 010     | Antarctica                             |
| 002     | 012     | Algeria                                |
| ...     | ...     | ...                                    |
| 003     | LAX     | Los Angeles International Airport      |
| 003     | SIN     | Singapore Changi International Airport |
| ...     | ...     | ...                                    |

我认为 JCache 是用于这些目的的最通用方式,但是如何将这些记录的顺序保存在缓存中,例如 LinkedHashMap?

(具体 JCache 实现的配置是可以接受的。)

编辑

这是我现在正在处理的遗留企业应用程序中的典型 One True Lookup Table (OTLT)。主排序键是group,辅助排序键是key

OTLT在性能上有一些劣势,所以我想使用缓存机制来解决这个劣势。

4

1 回答 1

1

Since you need to cache what looks like a map-of-maps model I would suggest you take also into account your access pattern (ie how your application reads these data). My guess is that you would need to do two things with these data:

  1. list all values available in a single group (eg to populate a "Country" drop-down)
  2. locate a single value by group and key (to display a user's "Country" in their profile page)

Given these assumed requirements, these are fulfilled with a Cache<String, LinkedHashMap<String, String>> structure. Use the group as the cache's key and a LinkedHashMap<String, String> of all key->value mappings in that group as the cache's value. In this arrangement, requirement 1 is fulfilled with a single lookup in the Cache, while requirement 2 is fulfilled with one lookup in the Cache (to obtain the LinkedHashMap key->value mappings) and one more lookup in the LinkedHashMap. Note that instead of a LinkedHashMap as the cache's value type you can use a TreeMap, essentially any kind of map that maintains iteration order will do.

Due to requirement 1, I would avoid a group/key mangling scheme (like using group + "-" + key as you cache's key) as it would require a full iteration of the cache's entry set (with Cache.iterator()) and pattern matching each one of the keys to decide whether it belongs to the group you're looking for or not.

The JCache-standard way to create such a Cache with the above configuration would be something like this:

MutableConfiguration<String, LinkedHashMap> config = new MutableConfiguration<String, LinkedHashMap>()
         .setTypes(String.class, LinkedHashMap.class);
CachingProvider provider = Caching.getCachingProvider();
CacheManager defaultCacheManager = provider.getCacheManager();
Cache<String, LinkedHashMap> cache = defaultCacheManager
        .createCache("cache", config);

Observe that due to Java generics limitations, it is not possible to do this:

MutableConfiguration<String, LinkedHashMap<String, String>> config = new MutableConfiguration<String, LinkedHashMap<String, String>()
        .setTypes(String.class, LinkedHashMap<String, String>.class);

Also, you may consider implementing a CacheLoader to have your cache populated from the lookup table, as well as a strategy for refreshing your cache contents (either via expiry or by explicitly evicting the cache contents).

于 2017-12-13T15:33:29.007 回答