XMLStatementBuilder
解析SQL节点,将定义的SQL节点信息构建成MappedStatement
对象。
1、MappedStatement
记录SQL节点信息,包含了很多属性,平时常见的属性有:
private String id;
private List<ResultMap> resultMaps;
private boolean useCache;
/**
* 记录缓存对象(二级缓存)
*/
private Cache cache;
/**
* sql片段集
*/
private SqlSource sqlSource;
private KeyGenerator keyGenerator;
除这些还有SqlCommandType、StatementType等等。
2、开启SQL节点解析
入口:parseStatementNode
。
一步一步看源码注释最清楚。
public void parseStatementNode() {
//NOTE. 节点id属性,对应Mapper接口中的方法名
String id = context.getStringAttribute("id");
//指定databaseId
String databaseId = context.getStringAttribute("databaseId");
//NOTE. 获取对应的SqlCommandType(select、insert、update、delete)
String nodeName = context.getNode().getNodeName();
SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
//NOTE: 是否刷新缓存
boolean flushCache = context.getBooleanAttribute("flushCache", !isSelect);
//NOTE: 是否使用二级缓存(select 语句默认使用缓存)
boolean useCache = context.getBooleanAttribute("useCache", isSelect);
boolean resultOrdered = context.getBooleanAttribute("resultOrdered", false);
// Include Fragments before parsing
//NOTE: <include>语句解析
XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);
includeParser.applyIncludes(context.getNode());
//NOTE: 解析parameterType(如传入一个对象)
String parameterType = context.getStringAttribute("parameterType");
Class<?> parameterTypeClass = resolveClass(parameterType);
//NOTE:一般不会配置,使用默认的XMLLanguagerDriver
String lang = context.getStringAttribute("lang");
LanguageDriver langDriver = getLanguageDriver(lang);
//NOTE: 解析<update/>等操作内部 的<SelectKey>内置节点
processSelectKeyNodes(id, parameterTypeClass, langDriver);
// Parse the SQL (pre: <selectKey> and <include> were parsed and removed)
KeyGenerator keyGenerator;
//NOTE: 定义MappedStatement的id,区别于其他SQL节点
String keyStatementId = id + SelectKeyGenerator.SELECT_KEY_SUFFIX;
keyStatementId = builderAssistant.applyCurrentN