2.1 mapping file parsing process analysis
MyBatis configuration file parsed by the parseConfiguration XMLConfigBuilder, which in turn parses the <properties>, <settings>, <typeAliases> peer node. As <mappers> node, parseConfiguration is at the end of its analytical methods were. Parsing logic is encapsulated in the portion mapperElement method:
. 1 Private void mapperElement (XNode parent) throws Exception { 2 IF (parent =! Null ) { . 3 for (XNode Child: parent.getChildren ()) { . 4 IF ( "Package" .equals (child.getName ())) { 5 // Get <package> name attribute node . 6 String mapperPackage = child.getStringAttribute ( "name" ); . 7 // Find the specified packet from the interface mapper and mapper interface for parsing in accordance with the mapping configuration . 8 configuration.addMappers (mapperPackage) ; . 9 } the else { 10 // Get resource / url / class attributes . 11 String Resource child.getStringAttribute = ( "Resource" ); 12 is String = child.getStringAttribute URL ( "URL" ); 13 is String mapperClass = child.getStringAttribute ( "class" ); 14 15 // Resource is not empty, and the other two are empty, from the loading configuration specified path 16 IF (Resource! = null && URL == null && mapperClass == null ) { . 17 ErrorContext.instance (). Resource ( Resource); 18 is the inputStream inputStream =Resources.getResourceAsStream (Resource); . 19 XMLMapperBuilder mapperParser = new new XMLMapperBuilder (inputStream, Configuration, Resource, configuration.getSqlFragments ()); 20 is // parse map file 21 is mapperParser.parse (); 22 is 23 is // URL is not empty, and the other two is empty, by loading the configuration url 24 } the else IF (Resource == null && url =! null && mapperClass == null {) 25 ErrorContext.instance () Resource (url);. 26 is the inputStream inputStream =Resources.getUrlAsStream (URL); 27 XMLMapperBuilder mapperParser = new new XMLMapperBuilder (inputStream, Configuration, URL, configuration.getSqlFragments ()); 28 // resolution mapping file 29 mapperParser.parse (); 30 31 is // mapperClass not empty, and the other two is empty, then the resolution mapping configured by mapperClass 32 } the else IF (Resource == null && URL == null && mapperClass =! null ) { 33 is Class mapperInterface = <?> Resources.classForName (mapperClass); 34 is configuration.addMapper (mapperInterface); 35 36 // the above conditions are not met, an exception is thrown 37 [ } the else { 38 is the throw new new BuilderException ( "A Element Mapper On May only the Specify A URL, or Resource class, But Not More Within last One." ); 39 } 40 } 41 } 42 } 43 }
The above codes are child nodes of the main logic traversed the mappers, and by what means a load map file or map information according to the attribute values of nodes is determined. Here, I put the configuration in the annotation content referred 映射信息
to as the carrier configuration is called XML 映射文件
. In MyBatis, a total of four load map files or messages manner. The first map file is loaded from the file system; the second way is by loading and parsing the URL mapping file; third loading by the interface mapper mapping information, the mapping information may be arranged in the annotation, the maps may be arranged in file. Finally, there are all the classes obtained by coating a package in a scanning manner, and a third mode for each class using the resolution mapping information.
Java annotations limited expressive power and flexibility, by way of comment and not nearly enough of MyBatis. So, for some of the more complex configuration information, we should be configured through XML way.
The next part is the focus of the analysis based on the parsing process XML mapping file, the following analysis mapping file parsing first entry:
. 1 public void the parse () { 2 // detect whether the mapping file has been parsed . 3 IF (! {Configuration.isResourceLoaded (Resource)) . 4 // parse mapper node . 5 ConfigurationElement (parser.evalNode ( "/ mapper" )); 6 // Add resource route to the "resolution resource sets' . 7 configuration.addLoadedResource (resource); . 8 // bind Mapper interfaces namespace . 9 bindMapperForNamespace (); 10 } . 11 12 is // processing node analysis unfinished 13 parsePendingResultMaps (); 14 parsePendingCacheRefs (); 15 parsePendingStatements (); 16 }
As above, the mapping logic includes three entry file parsing operation core, are as follows:
- Parsing mapper node
- By namespace binding Mapper Interface
- Processing node unfinished parsing
These three operations corresponding to logic, I will be analyzed successively in subsequent chapters. Here, take the first corresponding logical operation.
2.2 parse map file
Logic configured to parse each node in each configuration file are encapsulated in a corresponding method, these methods invoked by a unified method XMLMapperBuilder configurationElement class. Logic of the method is as follows:
. 1 Private void ConfigurationElement (XNode context) { 2 the try { . 3 // Get the namespace mapper . 4 String namespace = context.getStringAttribute ( "namespace" ); . 5 IF (namespace == null || namespace.equals ( "" )) { . 6 the throw new new BuilderException ( "CAN Not BE Mapper apos namespace empty" ); . 7 } . 8 . 9 // set the namespace to builderAssistant 10 builderAssistant.setCurrentNamespace (namespace); . 11 12 is //Analytical <cache-ref> node 13 is cacheRefElement (context.evalNode ( "Cache-REF" )); 14 15 // Analytical <cache> node 16 cacheElement (context.evalNode ( "Cache" )); . 17 18 is // obsolete configuration, not analyzed here . 19 parameterMapElement (context.evalNodes ( "/ Mapper / the parameterMap" )); 20 is 21 is // analytical <resultMap> node 22 is resultMapElements (context.evalNodes ( "/ Mapper / The resultMap" )); 23 is 24 / / analytical <sql> node 25 sqlElement (context.evalNodes ( "/ Mapper / SQL" )); 26 27 // 解析 <select>、...、<delete> 等节点 28 buildStatementFromContext(context.evalNodes("select|insert|update|delete")); 29 } catch (Exception e) { 30 throw new BuilderException("Error parsing Mapper XML. The XML location is '" + resource + "'. Cause: " + e, e); 31 } 32 }
pending upgrade. . .