Mybatis 原始碼學習(二) Mapper 介面和sql的對映
阿新 • • 發佈:2019-02-16
問題:xml中的sql語句是怎麼被對映到Mapper介面的一個方法上的?
弄明白了mapper是如何註冊的了以後,發現xml檔案中的namespace是關鍵。實際還是去找那個java介面檔案。那麼找到了介面檔案,註冊了mapper那這個mapper又是怎麼反過來找到xml中配置的sql的呢?
看mapper註冊的程式碼好想沒有發現這個對映關係。從新再看一下原始碼,這次要順利很很,很快找到了昨天那一串呼叫棧。
sqlSessionFactoryBuilder.build(inputStream);
return build(parser.parse());
parseConfiguration(parser.evalNode("/configuration"));
mapperElement(root.evalNode("mappers"));
然後找resource!=null的情況
public void parse() { if (!configuration.isResourceLoaded(resource)) { configurationElement(parser.evalNode("/mapper"));//****關鍵的操作藏在了這裡**** configuration.addLoadedResource(resource); bindMapperForNamespace(); //這裡就是去註冊mapper的地方 } parsePendingResultMaps(); parsePendingChacheRefs(); parsePendingStatements(); }
private void configurationElement(XNode context) { try { String namespace = context.getStringAttribute("namespace"); builderAssistant.setCurrentNamespace(namespace); cacheRefElement(context.evalNode("cache-ref")); cacheElement(context.evalNode("cache")); parameterMapElement(context.evalNodes("/mapper/parameterMap")); resultMapElements(context.evalNodes("/mapper/resultMap")); sqlElement(context.evalNodes("/mapper/sql")); buildStatementFromContext(context.evalNodes("select|insert|update|delete"));//看到這裡心裡就大概明白了 } catch (Exception e) { throw new RuntimeException("Error parsing Mapper XML. Cause: " + e, e); } }
繼續往下看呢,程式碼就很長了,注意到一點,這些配置並沒有關聯到mapper上,而是最終直接新增到了Configuration物件的
mappedStatements
mappedStatements 是一個map,而且他的key是namespace加id。
debug了一下:
果然key就是"com.tiantao.learn.mappers.UserMapper.selectUser" namespace加上id。
同時還有一個只一個id,這兩個都對應同一個物件。這麼說來這個id應該是全域性唯一的?!?!
記錄一下呼叫棧