在 MyBatis 中,二级缓存是可以共用的。这需要通过节点为命名空间配置参照缓存,比如像下面这样。
1 2 3 4 5 6 7 8 9 10 11
| <!-- Mapper1.xml --> <mapper namespace="xyz.coolblog.dao.Mapper1"> <!-- Mapper1 与 Mapper2 共用一个二级缓存 --> <cache-ref namespace="xyz.coolblog.dao.Mapper2"/> </mapper>
<!-- Mapper2.xml --> <mapper namespace="xyz.coolblog.dao.Mapper2"> <cache/> </mapper>
|
配置分析 cache-ref 的解析过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| private void cacheRefElement(XNode context) { if (context != null) { configuration.addCacheRef(builderAssistant.getCurrentNamespace(), context.getStringAttribute("namespace")); // 创建 CacheRefResolver 实例 CacheRefResolver cacheRefResolver = new CacheRefResolver( builderAssistant, context.getStringAttribute("namespace")); try { // 解析参照缓存 cacheRefResolver.resolveCacheRef(); } catch (IncompleteElementException e) { // 捕捉 IncompleteElementException 异常,并将 cacheRefResolver // 存入到 Configuration 的 incompleteCacheRefs 集合中 configuration.addIncompleteCacheRef(cacheRefResolver); } } }
|
节点的解析逻辑封装在了 CacheRefResolver 的resolveCacheRef方法中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| // -☆- CacheRefResolver public Cache resolveCacheRef() { // 调用 builderAssistant 的 useNewCache(namespace) 方法 return assistant.useCacheRef(cacheRefNamespace); }
// -☆- MapperBuilderAssistant public Cache useCacheRef(String namespace) { if (namespace == null) { throw new BuilderException("……"); } try { unresolvedCacheRef = true; // 根据命名空间从全局配置对象(Configuration)中查找相应的缓存实例 Cache cache = configuration.getCache(namespace); /* * 若未查找到缓存实例,此处抛出异常。这里存在两种情况导致未查找到 * cache 实例,分别如下: * 1.使用者在 <cache-ref> 中配置了一个不存在的命名空间, * 导致无法找到 cache 实例 * 2.使用者所引用的缓存实例还未创建 */ if (cache == null) { throw new IncompleteElementException("……"); } // 设置 cache 为当前使用缓存 currentCache = cache; unresolvedCacheRef = false; return cache; } catch (IllegalArgumentException e) { throw new IncompleteElementException("……"); } }
|