This is the 20th day of my participation in the August Text Challenge.More challenges in August
Sequence diagram
sequenceDiagram
participant A as XMLMapperBuilder
participant B as XMLStatementBuilder
participant C as XMLLanguageDriver
participant D as MapperBuilderAssistant
A ->> A : buildStatementFromContext
A ->> B : parseStatementNode
B ->> C : createSqlSource
C -->> B : SqlSource
B ->> D : addMappedStatement
The detailed steps
XMLMapperBuilder#configurationElement
/** * Parse the mapping file's lower node *@paramContext mapping file root */
private void configurationElement(XNode context) {
try {
// Reads the namespace of the current mapping file
String namespace = context.getStringAttribute("namespace");
if (namespace == null || namespace.equals("")) {
throw new BuilderException("Mapper's namespace cannot be empty");
}
builderAssistant.setCurrentNamespace(namespace);
// Resolve other configuration nodes in the mapping file
// Parse the cache label
cacheRefElement(context.evalNode("cache-ref"));
cacheElement(context.evalNode("cache"));
// Parse the parameter mapping
parameterMapElement(context.evalNodes("/mapper/parameterMap"));
// Parse the result set mapping
resultMapElements(context.evalNodes("/mapper/resultMap"));
// Parse SQL tags
sqlElement(context.evalNodes("/mapper/sql"));
// Process individual database operation statements
buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
} catch (Exception e) {
throw new BuilderException("Error parsing Mapper XML. The XML location is '" + resource + "'. Cause: "+ e, e); }}Copy the code
XMLMapperBuilder#buildStatementFromContext
private void buildStatementFromContext(List<XNode> list) {
// The global databaseId attribute is not empty
if(configuration.getDatabaseId() ! =null) {
buildStatementFromContext(list, configuration.getDatabaseId());
}
buildStatementFromContext(list, null);
}
private void buildStatementFromContext(List<XNode> list, String requiredDatabaseId) {
for (XNode context : list) {
// Create a parse object
final XMLStatementBuilder statementParser = new XMLStatementBuilder(configuration, builderAssistant, context, requiredDatabaseId);
try {
/ / parsing
statementParser.parseStatementNode();
} catch (IncompleteElementException e) {
// Put the unprocessed items into the container and retry laterconfiguration.addIncompleteStatement(statementParser); }}}Copy the code
XMLStatementBuilder#parseStatementNode
/** * parse select, INSERT, update, delete nodes */
public void parseStatementNode(a) {
// Read the current node ID and databaseId
String id = context.getStringAttribute("id");
String databaseId = context.getStringAttribute("databaseId");
// Verify that id matches databaseId. MyBatis allows multiple database configurations, so some statements only apply to specific databases
if(! databaseIdMatchesCurrent(id, databaseId,this.requiredDatabaseId)) {
return;
}
// Read the node name
String nodeName = context.getNode().getNodeName();
// Read and determine the statement type
SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
boolean flushCache = context.getBooleanAttribute("flushCache", !isSelect);
boolean useCache = context.getBooleanAttribute("useCache", isSelect);
boolean resultOrdered = context.getBooleanAttribute("resultOrdered".false);
// Process the Include node in the statement
// Include Fragments before parsing
XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);
includeParser.applyIncludes(context.getNode());
// Parameter type
String parameterType = context.getStringAttribute("parameterType");
/** * 1. Find the corresponding class in the alias mapper according to the attribute value * 2. If not in the alias mapper, the Class object */ corresponding to the Class name is createdClass<? > parameterTypeClass = resolveClass(parameterType);// Statement type, default is XMLLanguageDriver (created in the Configuration default constructor)
String lang = context.getStringAttribute("lang");
LanguageDriver langDriver = getLanguageDriver(lang);
/ / processing SelectKey node where KeyGenerator will be added to the Configuration. The keyGenerators
// Parse selectKey after includes and remove them.
processSelectKeyNodes(id, parameterTypeClass, langDriver);
// At this point, the
and
nodes have been parsed and deleted to begin SQL parsing
// Parse the SQL (pre: <selectKey> and <include> were parsed and removed)
KeyGenerator keyGenerator;
String keyStatementId = id + SelectKeyGenerator.SELECT_KEY_SUFFIX;
keyStatementId = builderAssistant.applyCurrentNamespace(keyStatementId, true);
// Determine if there is a resolved KeyGenerator
if (configuration.hasKeyGenerator(keyStatementId)) {
keyGenerator = configuration.getKeyGenerator(keyStatementId);
} else {
// Automatic key generation is used globally or whenever automatic key generation is enabled in this statement
keyGenerator = context.getBooleanAttribute("useGeneratedKeys",
configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType))
? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE;
}
// Create the SqlSource based on the LanguageDriver obtained
SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);
// Read the configuration properties
StatementType statementType = StatementType.valueOf(context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
Integer fetchSize = context.getIntAttribute("fetchSize");
Integer timeout = context.getIntAttribute("timeout");
String parameterMap = context.getStringAttribute("parameterMap");
String resultType = context.getStringAttribute("resultType"); Class<? > resultTypeClass = resolveClass(resultType); String resultMap = context.getStringAttribute("resultMap");
String resultSetType = context.getStringAttribute("resultSetType");
ResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);
if (resultSetTypeEnum == null) {
resultSetTypeEnum = configuration.getDefaultResultSetType();
}
String keyProperty = context.getStringAttribute("keyProperty");
String keyColumn = context.getStringAttribute("keyColumn");
String resultSets = context.getStringAttribute("resultSets");
// Create the MappedStatement object with the help of the MapperBuilderAssistant and write it to the Configuration
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
resultSetTypeEnum, flushCache, useCache, resultOrdered,
keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);
}
Copy the code
This is Mybatis parsing the select | insert | update process | delete tags.