Mybatisロード解析Mapper(xml)ファイル第二話
もっと読む
Sql Session Factory初期化:http://donald-draper.iteye.com/admin/blogs/2331917
Mybatisロード解析Mapper(xml)ファイル第一話:http://donald-draper.iteye.com/blog/2333125
Mapper対応のxmlファイルを解析すると、実際には解析xmlのmapper Xnode、具体的にはnamespace属性、cache、cache-ref、parameterMap、reultMap、sql、およびselect insert udateサブノードになります。前の記事では、Manacheceという属性の解析を行います。及びselect insert 124アップデテサブノードの解析
まず次の方法から見ます。
//Mapper xmlファイルを読み込み、解析する
//その中でkeyはclassのフルネームで、comp.mapper.UserMapper
result MapElements(context.eval Nodes);
//エルゴード解析resultMapノード
//ResultMapを作成し、ResultMapマッピング関係をconfigrationに追加します。
reult Maps=new StrictMap(「Result Maps collection」);
HashMap,keyはResultMapのグローバルネーム空間idです。
Sql Session Factory初期化:http://donald-draper.iteye.com/admin/blogs/2331917
Mybatisロード解析Mapper(xml)ファイル第一話:http://donald-draper.iteye.com/blog/2333125
Mapper対応のxmlファイルを解析すると、実際には解析xmlのmapper Xnode、具体的にはnamespace属性、cache、cache-ref、parameterMap、reultMap、sql、およびselect insert udateサブノードになります。前の記事では、Manacheceという属性の解析を行います。及びselect insert 124アップデテサブノードの解析
まず次の方法から見ます。
//Mapper xmlファイルを読み込み、解析する
private void mapperElement(XNode parent)
throws Exception
{
if(parent != null)
{
for(Iterator i$ = parent.getChildren().iterator(); i$.hasNext();)
{
XNode child = (XNode)i$.next();
if("package".equals(child.getName()))
{
String mapperPackage = child.getStringAttribute("name");
configuration.addMappers(mapperPackage);
} else
{
String resource = child.getStringAttribute("resource");
String url = child.getStringAttribute("url");
String mapperClass = child.getStringAttribute("class");
// resource, Mapper
if(resource != null && url == null && mapperClass == null)
{
ErrorContext.instance().resource(resource);
// Mapper resource
InputStream inputStream = Resources.getResourceAsStream(resource);
XMLMapperBuilder
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
mapperParser.parse();
} else
if(resource == null && url != null && mapperClass == null)
{
ErrorContext.instance().resource(url);
InputStream inputStream = Resources.getUrlAsStream(url);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
mapperParser.parse();
} else
//
// class, Mapper
if(resource == null && url == null && mapperClass != null)
{
Class mapperInterface = Resources.classForName(mapperClass);
//mapperInterface configuration
configuration.addMapper(mapperInterface);
} else
{
throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
}
}
}
}
}
//XMLMapperBuiderpublic class XMLMapperBuilder extends BaseBuilder
{
private XPathParser parser;
private MapperBuilderAssistant builderAssistant;
private Map sqlFragments;
private String resource;
// XMLMapperBuilder
public XMLMapperBuilder(InputStream inputStream, Configuration configuration, String resource, Map sqlFragments)
{
this(new XPathParser(inputStream, true, configuration.getVariables(), new XMLMapperEntityResolver()), configuration, resource, sqlFragments);
}
private XMLMapperBuilder(XPathParser parser, Configuration configuration, String resource, Map sqlFragments)
{
super(configuration);
// MapperBuilderAssistant
builderAssistant = new MapperBuilderAssistant(configuration, resource);
this.parser = parser;
this.sqlFragments = sqlFragments;
this.resource = resource;
}
public void parse()
{
if(!configuration.isResourceLoaded(resource))
{
// configuration , Mapper xml ,
configurationElement(parser.evalNode("/mapper"));
// configuration Set resource
configuration.addLoadedResource(resource);
// Mapper
bindMapperForNamespace();
}
// configuration ResultMaps
parsePendingResultMaps();
// configuration ChacheRefs
parsePendingChacheRefs();
// configuration Statements
parsePendingStatements();
}
// mapper Xnode ,namespace,cache,cache-ref,parameterMap,resultMap,
//sql, select|insert|update|delete
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((new StringBuilder()).append("Error parsing Mapper XML. Cause: ").append(e).toString(), e);
}
}
}
//Configration、Mapper xmlファイル名をSet loaded Resourceに追加します。//その中でkeyはclassのフルネームで、comp.mapper.UserMapper
public void addLoadedResource(String resource)
{
loadedResources.add(resource);
}
//resultMapの設定result MapElements(context.eval Nodes);
//XMLMapperBuider//エルゴード解析resultMapノード
private void resultMapElements(List list)
throws Exception
{
for(Iterator i$ = list.iterator(); i$.hasNext();)
{
XNode resultMapNode = (XNode)i$.next();
try
{
// resultMap
resultMapElement(resultMapNode);
}
catch(IncompleteElementException e) { }
}
}
// resultMap
private ResultMap resultMapElement(XNode resultMapNode)
throws Exception
{
// resultMapElement
return resultMapElement(resultMapNode, Collections.emptyList());
}
// resultMap
private ResultMap resultMapElement(XNode resultMapNode, List additionalResultMappings)
throws Exception
{
ResultMapResolver resultMapResolver;
ErrorContext.instance().activity((new StringBuilder()).append("processing ").append(resultMapNode.getValueBasedIdentifier()).toString());
// resultMap id,type,extends,autoMapping
String id = resultMapNode.getStringAttribute("id", resultMapNode.getValueBasedIdentifier());
String type = resultMapNode.getStringAttribute("type", resultMapNode.getStringAttribute("ofType", resultMapNode.getStringAttribute("resultType", resultMapNode.getStringAttribute("javaType"))));
String extend = resultMapNode.getStringAttribute("extends");
Boolean autoMapping = resultMapNode.getBooleanAttribute("autoMapping", null);
Class typeClass = resolveClass(type);
Discriminator discriminator = null;
List resultMappings = new ArrayList();
resultMappings.addAll(additionalResultMappings);
List resultChildren = resultMapNode.getChildren();
//resultMap result , result , ResultMapping
// resultMappings,ArrayList
for(Iterator i$ = resultChildren.iterator(); i$.hasNext();)
{
XNode resultChild = (XNode)i$.next();
if("constructor".equals(resultChild.getName()))
//constructor
processConstructorElement(resultChild, typeClass, resultMappings);
else
if("discriminator".equals(resultChild.getName()))
{
//discriminator
discriminator = processDiscriminatorElement(resultChild, typeClass, resultMappings);
} else
{
//result , id , ResultFlag.ID flags
ArrayList flags = new ArrayList();
if("id".equals(resultChild.getName()))
flags.add(ResultFlag.ID);
resultMappings.add(buildResultMappingFromContext(resultChild, typeClass, flags));
}
}
// resultMapResolver
resultMapResolver = new ResultMapResolver(builderAssistant, id, typeClass, extend, discriminator, resultMappings, autoMapping);
return resultMapResolver.resolve();
IncompleteElementException e;
e;
// IncompleteElementException, resultMapResolver IncompleteResultMap
//LinkedList
configuration.addIncompleteResultMap(resultMapResolver);
throw e;
}
// constructor
private void processConstructorElement(XNode resultChild, Class resultType, List resultMappings)
throws Exception
{
List argChildren = resultChild.getChildren();
XNode argChild;
ArrayList flags;
for(Iterator i$ = argChildren.iterator(); i$.hasNext(); resultMappings.add(buildResultMappingFromContext(argChild, resultType, flags)))
{
argChild = (XNode)i$.next();
flags = new ArrayList();
flags.add(ResultFlag.CONSTRUCTOR);
if("idArg".equals(argChild.getName()))
flags.add(ResultFlag.ID);
}
}
// discriminator
private Discriminator processDiscriminatorElement(XNode context, Class resultType, List resultMappings)
throws Exception
{
String column = context.getStringAttribute("column");
String javaType = context.getStringAttribute("javaType");
String jdbcType = context.getStringAttribute("jdbcType");
String typeHandler = context.getStringAttribute("typeHandler");
Class javaTypeClass = resolveClass(javaType);
Class typeHandlerClass = resolveClass(typeHandler);
JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType);
Map discriminatorMap = new HashMap();
String value;
String resultMap;
for(Iterator i$ = context.getChildren().iterator(); i$.hasNext(); discriminatorMap.put(value, resultMap))
{
XNode caseChild = (XNode)i$.next();
value = caseChild.getStringAttribute("value");
resultMap = caseChild.getStringAttribute("resultMap", processNestedResultMappings(caseChild, resultMappings));
}
return builderAssistant.buildDiscriminator(resultType, column, javaTypeClass, jdbcTypeEnum, typeHandlerClass, discriminatorMap);
}
//result id ResultMapping
private ResultMapping buildResultMappingFromContext(XNode context, Class resultType, ArrayList flags)
throws Exception
{
String property = context.getStringAttribute("property");
String column = context.getStringAttribute("column");
String javaType = context.getStringAttribute("javaType");
String jdbcType = context.getStringAttribute("jdbcType");
String nestedSelect = context.getStringAttribute("select");
String nestedResultMap = context.getStringAttribute("resultMap", processNestedResultMappings(context, Collections.emptyList()));
String notNullColumn = context.getStringAttribute("notNullColumn");
String columnPrefix = context.getStringAttribute("columnPrefix");
String typeHandler = context.getStringAttribute("typeHandler");
Class javaTypeClass = resolveClass(javaType);
Class typeHandlerClass = resolveClass(typeHandler);
JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType);
return builderAssistant.buildResultMapping(resultType, property, column, javaTypeClass, jdbcTypeEnum, nestedSelect, nestedResultMap, notNullColumn, columnPrefix, typeHandlerClass, flags);
}
// resultMapping
public ResultMapping buildResultMapping(Class resultType, String property, String column, Class javaType, JdbcType jdbcType, String nestedSelect, String nestedResultMap,
String notNullColumn, String columnPrefix, Class typeHandler, List flags)
{
ResultMapping resultMapping = assembleResultMapping(resultType, property, column, javaType, jdbcType, nestedSelect, nestedResultMap, notNullColumn, columnPrefix, typeHandler, flags);
return resultMapping;
}
// ResultMapping
private ResultMapping assembleResultMapping(Class resultType, String property, String column, Class javaType, JdbcType jdbcType, String nestedSelect, String nestedResultMap,
String notNullColumn, String columnPrefix, Class typeHandler, List flags)
{
Class javaTypeClass = resolveResultJavaType(resultType, property, javaType);
TypeHandler typeHandlerInstance = resolveTypeHandler(javaTypeClass, typeHandler);
List composites = parseCompositeColumnName(column);
if(composites.size() > 0)
column = null;
org.apache.ibatis.mapping.ResultMapping.Builder builder = new org.apache.ibatis.mapping.ResultMapping.Builder(configuration, property, column, javaTypeClass);
builder.jdbcType(jdbcType);
builder.nestedQueryId(applyCurrentNamespace(nestedSelect, true));
builder.nestedResultMapId(applyCurrentNamespace(nestedResultMap, true));
builder.typeHandler(typeHandlerInstance);
builder.flags(((List) (flags != null ? flags : ((List) (new ArrayList())))));
builder.composites(composites);
builder.notNullColumns(parseMultipleColumnNames(notNullColumn));
builder.columnPrefix(columnPrefix);
return builder.build();
}
//ResultMappingpublic class ResultMapping
{
public static class Builder
{
public Builder javaType(Class javaType)
{
resultMapping.javaType = javaType;
return this;
}
// resultMapping
public ResultMapping build()
{
validate();
// flag, unmodifiableList
resultMapping.flags = Collections.unmodifiableList(resultMapping.flags);
resultMapping.composites = Collections.unmodifiableList(resultMapping.composites);
resolveTypeHandler();
return resultMapping;
}
private void resolveTypeHandler()
{
if(resultMapping.typeHandler == null && resultMapping.javaType != null)
{
// configuration typeHandlerRegistry
Configuration configuration = resultMapping.configuration;
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
// typeHandlerRegistry typeHandler
resultMapping.typeHandler = typeHandlerRegistry.getTypeHandler(resultMapping.javaType, resultMapping.jdbcType);
}
}
// builder
public Builder(Configuration configuration, String property, String column, Class javaType)
{
resultMapping = new ResultMapping();
resultMapping.configuration = configuration;
resultMapping.property = property;
resultMapping.column = column;
resultMapping.javaType = javaType;
resultMapping.flags = new ArrayList();
resultMapping.composites = new ArrayList();
}
}
//ResultFlagGpublic final class ResultFlag extends Enum
{
public static ResultFlag[] values()
{
return (ResultFlag[])$VALUES.clone();
}
public static ResultFlag valueOf(String name)
{
return (ResultFlag)Enum.valueOf(org/apache/ibatis/mapping/ResultFlag, name);
}
private ResultFlag(String s, int i)
{
super(s, i);
}
public static final ResultFlag ID;
public static final ResultFlag CONSTRUCTOR;
private static final ResultFlag $VALUES[];
static
{
ID = new ResultFlag("ID", 0);
CONSTRUCTOR = new ResultFlag("CONSTRUCTOR", 1);
$VALUES = (new ResultFlag[] {
ID, CONSTRUCTOR
});
}
}
//ResultMapResolover、ResultMapプロセッサpublic class ResultMapResolver
{
private final MapperBuilderAssistant assistant;
private String id;//id
private Class type;// type
private String extend;
private Discriminator discriminator;
private List resultMappings;
private Boolean autoMapping;
public ResultMapResolver(MapperBuilderAssistant assistant, String id, Class type, String extend, Discriminator discriminator, List resultMappings, Boolean autoMapping)
{
this.assistant = assistant;
this.id = id;
this.type = type;
this.extend = extend;
this.discriminator = discriminator;
this.resultMappings = resultMappings;
this.autoMapping = autoMapping;
}
public ResultMap resolve()
{
return assistant.addResultMap(id, type, extend, discriminator, resultMappings, autoMapping);
}
}
//MapperBuilder Asistant//ResultMapを作成し、ResultMapマッピング関係をconfigrationに追加します。
public ResultMap addResultMap(String id, Class type, String extend, Discriminator discriminator, List resultMappings, Boolean autoMapping)
{
// ResultMap
id = applyCurrentNamespace(id, false);
extend = applyCurrentNamespace(extend, true);
// ResultMap
org.apache.ibatis.mapping.ResultMap.Builder resultMapBuilder =
new org.apache.ibatis.mapping.ResultMap.Builder(configuration, id, type, resultMappings, autoMapping);
ResultMap resultMap;
if(extend != null)
{
// true, configuration ResultMap, IncompleteElementException
if(!configuration.hasResultMap(extend))
throw new IncompleteElementException((new StringBuilder()).append("Could not find a parent resultmap with id '").append(extend).append("'").toString());
resultMap = configuration.getResultMap(extend);
List extendedResultMappings = new ArrayList(resultMap.getResultMappings());
extendedResultMappings.removeAll(resultMappings);
boolean declaresConstructor = false;
Iterator i$ = resultMappings.iterator();
do
{
if(!i$.hasNext())
break;
ResultMapping resultMapping = (ResultMapping)i$.next();
if(!resultMapping.getFlags().contains(ResultFlag.CONSTRUCTOR))
continue;
declaresConstructor = true;
break;
} while(true);
if(declaresConstructor)
{
Iterator extendedResultMappingsIter = extendedResultMappings.iterator();
do
{
if(!extendedResultMappingsIter.hasNext())
break;
if(((ResultMapping)extendedResultMappingsIter.next()).getFlags().contains(ResultFlag.CONSTRUCTOR))
extendedResultMappingsIter.remove();
} while(true);
}
resultMappings.addAll(extendedResultMappings);
}
resultMapBuilder.discriminator(discriminator);
// resultMap
resultMap = resultMapBuilder.build();
// resultMap configuration
configuration.addResultMap(resultMap);
return resultMap;
}
//resultMapマッピング関係をconfigrationに追加するreult Maps=new StrictMap(「Result Maps collection」);
HashMap,keyはResultMapのグローバルネーム空間idです。
public void addResultMap(ResultMap rm)
{
resultMaps.put(rm.getId(), rm);
checkLocallyForDiscriminatedNestedResultMaps(rm);
checkGloballyForDiscriminatedNestedResultMaps(rm);
}
//ResultMappublic class ResultMap
{
private String id;
private Class type;
private List resultMappings;
private List idResultMappings;
private List constructorResultMappings;
private List propertyResultMappings;
private Set mappedColumns;
private Discriminator discriminator;
private boolean hasNestedResultMaps;
private boolean hasNestedQueries;
private Boolean autoMapping;
public static class Builder
{
public ResultMap build()
{
if(resultMap.id == null)
throw new IllegalArgumentException("ResultMaps must have an id");
resultMap.mappedColumns = new HashSet();
resultMap.idResultMappings = new ArrayList();
resultMap.constructorResultMappings = new ArrayList();
resultMap.propertyResultMappings = new ArrayList();
Iterator i$ = resultMap.resultMappings.iterator();
do
{
if(!i$.hasNext())
break;
ResultMapping resultMapping = (ResultMapping)i$.next();
resultMap.hasNestedQueries = resultMap.hasNestedQueries || resultMapping.getNestedQueryId() != null;
resultMap.hasNestedResultMaps = resultMap.hasNestedResultMaps || resultMapping.getNestedResultMapId() != null;
String column = resultMapping.getColumn();
if(column != null)
resultMap.mappedColumns.add(column.toUpperCase(Locale.ENGLISH));
else
if(resultMapping.isCompositeResult())
{
Iterator i$ = resultMapping.getComposites().iterator();
do
{
if(!i$.hasNext())
break;
ResultMapping compositeResultMapping = (ResultMapping)i$.next();
String compositeColumn = compositeResultMapping.getColumn();
if(compositeColumn != null)
resultMap.mappedColumns.add(compositeColumn.toUpperCase(Locale.ENGLISH));
} while(true);
}
if(resultMapping.getFlags().contains(ResultFlag.CONSTRUCTOR))
resultMap.constructorResultMappings.add(resultMapping);
else
resultMap.propertyResultMappings.add(resultMapping);
if(resultMapping.getFlags().contains(ResultFlag.ID))
resultMap.idResultMappings.add(resultMapping);
} while(true);
if(resultMap.idResultMappings.isEmpty())
resultMap.idResultMappings.addAll(resultMap.resultMappings);
resultMap.resultMappings = Collections.unmodifiableList(resultMap.resultMappings);
resultMap.idResultMappings = Collections.unmodifiableList(resultMap.idResultMappings);
resultMap.constructorResultMappings = Collections.unmodifiableList(resultMap.constructorResultMappings);
resultMap.propertyResultMappings = Collections.unmodifiableList(resultMap.propertyResultMappings);
resultMap.mappedColumns = Collections.unmodifiableSet(resultMap.mappedColumns);
return resultMap;
}
}
}
の から、resultMapノードの が かります。まず、result Mapのid、typeなどの を し、そのサブノードreult、construct、discriminatorを します。resultノードに して、column、property、jdbcTypeなどの を して、ResultMappingに して、result Mappings の でArayListを します。 にレスポンスMapのid、typeなどの と
resultMappingsはResultMapを し、extedの ResultMapが しない は、Incompleete Element Exceptionを り し、configrationに し、Incomplette Result Map-linkedListに する は、 されたconfigrationのreltMapsに まれる。
// sql
sql Element(context.eval Nodes);
//すべてのsqlノードを する private void sqlElement(List list)
throws Exception
{
if(configuration.getDatabaseId() != null)
// ,
sqlElement(list, configuration.getDatabaseId());
// sqlElement
sqlElement(list, null);
}
// sql
private void sqlElement(List list, String requiredDatabaseId)
throws Exception
{
Iterator i$ = list.iterator();
do
{
if(!i$.hasNext())
break;
XNode context = (XNode)i$.next();
// sql databaseId,id,
String databaseId = context.getStringAttribute("databaseId");
String id = context.getStringAttribute("id");
id = builderAssistant.applyCurrentNamespace(id, false);
if(databaseIdMatchesCurrent(id, databaseId, requiredDatabaseId))
// sql sqlFragments-Map , select|insert|update|delete
sqlFragments.put(id, context);
} while(true);
}
// sql requiredDatabaseId
private boolean databaseIdMatchesCurrent(String id, String databaseId, String requiredDatabaseId)
{
if(requiredDatabaseId != null)
{
if(!requiredDatabaseId.equals(databaseId))
return false;
}
else
{
if(databaseId != null)
return false;
// databaseId requiredDatabaseId , null,
// configuration sqlFragments id sqlFragment
if(sqlFragments.containsKey(id))
{
XNode context = (XNode)sqlFragments.get(id);
// sql databaseId , false
if(context.getStringAttribute("databaseId") != null)
return false;
}
}
return true;
}
から Sqlノードは、SqlノードをXnodeとidマッピング に させ、sql Fragmens-HashMapに することであることが かる。
//select'insert 124 udate statementを する
buildSttement FroomCotext(context.eval Nodes);
//select'insert 124 udateノード の private void buildStatementFromContext(List list)
{
if(configuration.getDatabaseId() != null)
buildStatementFromContext(list, configuration.getDatabaseId());
// buildStatementFromContext
buildStatementFromContext(list, null);
}
// select|insert|update|delete
private void buildStatementFromContext(List list, String requiredDatabaseId)
{
for(Iterator i$ = list.iterator(); i$.hasNext();)
{
XNode context = (XNode)i$.next();
// Xnode XMLStatementBuilder
XMLStatementBuilder statementParser = new XMLStatementBuilder(configuration, builderAssistant, context, requiredDatabaseId);
try
{
// select|insert|update|delete-Xnode , MapStatement, configuration
//mappedStatements Map ,Map
statementParser.parseStatementNode();
}
catch(IncompleteElementException e)
{
// , statementParser
//configuration IncompleteStatement ,LinkedList
configuration.addIncompleteStatement(statementParser);
}
}
}
//XMLStatement Buiderpublic class XMLStatementBuilder extends BaseBuilder
{
public XMLStatementBuilder(Configuration configuration, MapperBuilderAssistant builderAssistant, XNode context)
{
this(configuration, builderAssistant, context, null);
}
public XMLStatementBuilder(Configuration configuration, MapperBuilderAssistant builderAssistant, XNode context, String databaseId)
{
super(configuration);
this.builderAssistant = builderAssistant;
this.context = context;
requiredDatabaseId = databaseId;
}
// Statement XNode
public void parseStatementNode()
{
// Statement XNode id,databaseId,fetchSize,timeout,fetchSize,
//timeout,parameterMap,parameterType,resultMap,resultType,statementType
//sqlCommandType,flushCache,useCache,resultOrdered,selectKey,keyProperty,keyColumn
String id = context.getStringAttribute("id");
String databaseId = context.getStringAttribute("databaseId");
// databaseId requiredDatabaseId ,
if(!databaseIdMatchesCurrent(id, databaseId, requiredDatabaseId))
return;
Integer fetchSize = context.getIntAttribute("fetchSize", null);
Integer timeout = context.getIntAttribute("timeout", null);
String parameterMap = context.getStringAttribute("parameterMap");
String parameterType = context.getStringAttribute("parameterType");
Class parameterTypeClass = resolveClass(parameterType);
String resultMap = context.getStringAttribute("resultMap");
String resultType = context.getStringAttribute("resultType");
String lang = context.getStringAttribute("lang");
LanguageDriver langDriver = getLanguageDriver(lang);
// resultType, Class
Class resultTypeClass = resolveClass(resultType);
String resultSetType = context.getStringAttribute("resultSetType");
// statementType , StatementType.PREPARED.toString()
StatementType statementType = StatementType.valueOf(context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
ResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);
String nodeName = context.getNode().getNodeName();
// sqlCommandType
SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
boolean flushCache = context.getBooleanAttribute("flushCache", Boolean.valueOf(!isSelect)).booleanValue();
boolean useCache = context.getBooleanAttribute("useCache", Boolean.valueOf(isSelect)).booleanValue();
boolean resultOrdered = context.getBooleanAttribute("resultOrdered", Boolean.valueOf(false)).booleanValue();
XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);
includeParser.applyIncludes(context.getNode());
// selectKey
List selectKeyNodes = context.evalNodes("selectKey");
if(configuration.getDatabaseId() != null)
parseSelectKeyNodes(id, selectKeyNodes, parameterTypeClass, langDriver, configuration.getDatabaseId());
// SelectKeys
parseSelectKeyNodes(id, selectKeyNodes, parameterTypeClass, langDriver, null);
SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);
String keyProperty = context.getStringAttribute("keyProperty");
String keyColumn = context.getStringAttribute("keyColumn");
String keyStatementId = (new StringBuilder()).append(id).append("!selectKey").toString();
// selectKey, id
keyStatementId = builderAssistant.applyCurrentNamespace(keyStatementId, true);
KeyGenerator keyGenerator;
// keyStatementId KeyGenerator, KeyGenerator
if(configuration.hasKeyGenerator(keyStatementId))
keyGenerator = configuration.getKeyGenerator(keyStatementId);
else
// KeyGenerator,
// useGeneratedKeys , true, KeyGenerator Jdbc3KeyGenerator
// useGeneratedKeys , isUseGeneratedKeys SqlCommandType.INSERT
// , , KeyGenerator NoKeyGenerator
//KeyGenerator , ,
keyGenerator = ((KeyGenerator) (context.getBooleanAttribute("useGeneratedKeys", Boolean.valueOf(configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType))).booleanValue() ? ((KeyGenerator) (new Jdbc3KeyGenerator())) : ((KeyGenerator) (new NoKeyGenerator()))));
// select|insert|update|delete , MappedStatement
// configuration mappedStatements Map ,Map
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache, resultOrdered, keyGenerator, keyProperty, keyColumn, databaseId, langDriver);
}
//SelectKeyノード の public void parseSelectKeyNodes(String parentId, List list, Class parameterTypeClass, LanguageDriver langDriver, String skRequiredDatabaseId)
{
Iterator i$ = list.iterator();
do
{
if(!i$.hasNext())
break;
XNode nodeToHandle = (XNode)i$.next();
String id = (new StringBuilder()).append(parentId).append("!selectKey").toString();
String databaseId = nodeToHandle.getStringAttribute("databaseId");
if(databaseIdMatchesCurrent(id, databaseId, skRequiredDatabaseId))
parseSelectKeyNode(id, nodeToHandle, parameterTypeClass, langDriver, databaseId);
} while(true);
}
//SelectKeyノード を し、 に する public void parseSelectKeyNode(String id, XNode nodeToHandle, Class parameterTypeClass, LanguageDriver langDriver, String databaseId)
{
// SelectKey resultType,keyProperty,statementType,useCache,keyGenerator
//fetchSize,timeout,flushCache,parameterMap,resultMap
String resultType = nodeToHandle.getStringAttribute("resultType");
Class resultTypeClass = resolveClass(resultType);
StatementType statementType = StatementType.valueOf(nodeToHandle.getStringAttribute("statementType", StatementType.PREPARED.toString()));
String keyProperty = nodeToHandle.getStringAttribute("keyProperty");
boolean executeBefore = "BEFORE".equals(nodeToHandle.getStringAttribute("order", "AFTER"));
boolean useCache = false;
boolean resultOrdered = false;
KeyGenerator keyGenerator = new NoKeyGenerator();
Integer fetchSize = null;
Integer timeout = null;
boolean flushCache = false;
String parameterMap = null;
String resultMap = null;
ResultSetType resultSetTypeEnum = null;
SqlSource sqlSource = langDriver.createSqlSource(configuration, nodeToHandle, parameterTypeClass);
SqlCommandType sqlCommandType = SqlCommandType.SELECT;
// SelectKey , MappedStatement,
//configuration mappedStatements Map Map
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache, resultOrdered, keyGenerator, keyProperty, null, databaseId, langDriver);
//
id = builderAssistant.applyCurrentNamespace(id, false);
// configuration mappedStatements Map , keyStatement
MappedStatement keyStatement = configuration.getMappedStatement(id, false);
// SelectKeyGenerator, configuration keyGenerators-Map
configuration.addKeyGenerator(id, new SelectKeyGenerator(keyStatement, executeBefore));
nodeToHandle.getParent().getNode().removeChild(nodeToHandle.getNode());
}
//configration
//keyGeneratorsと のマッピングを してkeyGeneratorsに します。
//keyGenerators:Mappublic void addKeyGenerator(String id, KeyGenerator keyGenerator)
{
keyGenerators.put(id, keyGenerator);
}
この に ります
//selectコーディネートノードの に づいて、Mapped Sttementを する
//configrationのmapped SttementsのMapに
Stildesistant. addMappedeSttement(id、sql Source、statementType、sqlCommmadTypee、fetSize、timeout、parameterMap、parameterTypeClass、reultMap、reulttTyypeClass、recucutttttttttCleleclass、OretsesesesesesesesesesesesesesesesecucucucucucucucuttttttttttttttttdedededededededededededededededededededededededededetttttttttttttttttgDriver);
//MapperBuilder Asistant public MappedStatement addMappedStatement(String id, SqlSource sqlSource, StatementType statementType, SqlCommandType sqlCommandType, Integer fetchSize, Integer timeout, String parameterMap,
Class parameterType, String resultMap, Class resultType, ResultSetType resultSetType, boolean flushCache, boolean useCache, boolean resultOrdered,
KeyGenerator keyGenerator, String keyProperty, String keyColumn, String databaseId, LanguageDriver lang)
{
if(unresolvedCacheRef)
{
// , IncompleteElementException
throw new IncompleteElementException("Cache-ref not yet resolved");
} else
{
// nameSpace
id = applyCurrentNamespace(id, false);
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
org.apache.ibatis.mapping.MappedStatement.Builder statementBuilder = new org.apache.ibatis.mapping.MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType);
statementBuilder.resource(resource);
statementBuilder.fetchSize(fetchSize);
statementBuilder.statementType(statementType);
statementBuilder.keyGenerator(keyGenerator);
statementBuilder.keyProperty(keyProperty);
statementBuilder.keyColumn(keyColumn);
statementBuilder.databaseId(databaseId);
statementBuilder.lang(lang);
statementBuilder.resultOrdered(resultOrdered);
setStatementTimeout(timeout, statementBuilder);
setStatementParameterMap(parameterMap, parameterType, statementBuilder);
setStatementResultMap(resultMap, resultType, resultSetType, statementBuilder);
setStatementCache(isSelect, flushCache, useCache, currentCache, statementBuilder);
// statement , MappedStatement
MappedStatement statement = statementBuilder.build();
// statement, configuration mappedStatements Map
configuration.addMappedStatement(statement);
return statement;
}
}
//Mapped Sttementpublic final class MappedStatement
{
private String resource;
private Configuration configuration;
private String id;
private Integer fetchSize;
private Integer timeout;
private StatementType statementType;
private ResultSetType resultSetType;
private SqlSource sqlSource;
private Cache cache;
private ParameterMap parameterMap;
private List resultMaps;
private boolean flushCacheRequired;
private boolean useCache;
private boolean resultOrdered;
private SqlCommandType sqlCommandType;
private KeyGenerator keyGenerator;
private String keyProperties[];
private String keyColumns[];
private boolean hasNestedResultMaps;
private String databaseId;
private Log statementLog;
private LanguageDriver lang;
//MappedStatement
public static class Builder
{
public MappedStatement build()
{
if(!$assertionsDisabled && mappedStatement.configuration == null)
throw new AssertionError();
if(!$assertionsDisabled && mappedStatement.id == null)
throw new AssertionError();
if(!$assertionsDisabled && mappedStatement.sqlSource == null)
throw new AssertionError();
if(!$assertionsDisabled && mappedStatement.lang == null)
{
throw new AssertionError();
} else
{
mappedStatement.resultMaps = Collections.unmodifiableList(mappedStatement.resultMaps);
return mappedStatement;
}
}
}
// sql BoundSql
public BoundSql getBoundSql(Object parameterObject)
{
BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
List parameterMappings = boundSql.getParameterMappings();
if(parameterMappings == null || parameterMappings.size() <= 0)
boundSql = new BoundSql(configuration, boundSql.getSql(), parameterMap.getParameterMappings(), parameterObject);
Iterator i$ = boundSql.getParameterMappings().iterator();
do
{
if(!i$.hasNext())
break;
ParameterMapping pm = (ParameterMapping)i$.next();
String rmId = pm.getResultMapId();
if(rmId != null)
{
// rmId configuration ResultMap
ResultMap rm = configuration.getResultMap(rmId);
if(rm != null)
// hasNestedResultMaps
hasNestedResultMaps |= rm.hasNestedResultMaps();
}
} while(true);
return boundSql;
}
}
//BoundSql、sqlの public class BoundSql
{
private String sql;
private List parameterMappings;
private Object parameterObject;
private Map additionalParameters;
private MetaObject metaParameters;
public BoundSql(Configuration configuration, String sql, List parameterMappings, Object parameterObject)
{
this.sql = sql;
this.parameterMappings = parameterMappings;
this.parameterObject = parameterObject;
additionalParameters = new HashMap();
metaParameters = configuration.newMetaObject(additionalParameters);
}
public String getSql()
{
return sql;
}
}
から かるように、 select_insert_udate_Xnode は、まずノード をXMLSTAtement Buiderに し、XMLSTAtement Builderによって され、XMLSTAtement_Builderが すると、statementノードXnodeの キャッシュがExcomplectされていない。XMLStatement BuiderをconfigurationのIncompletSttementセットに し、
Linked List;キャッシュ が されているなら、SelectKeyノード を し、
SelectKeyノードとの を し、configrationのmapped SttementsのMapに し、Mapは、keySttementに づいてSelectKeyGeneratorを し、configrationのkeyGeneratos-Mapに し、SelectKeyノードがない 、SelectKeyノードは、statementノードのuseGenerate edKeys とグローバルプロファイル isUseGeneratodKeysとSql Command Type.INSERTによって するKeyGeneratorが される。statementノードとKeyGeneratorによって、MapperStatimentを し、configrationのmapped SttementのMapに します。
//Mapperを びつける
bindMapper ForNamespace();
private void bindMapperForNamespace()
{
// MapperBuilderAssistant
String namespace = builderAssistant.getCurrentNamespace();
if(namespace != null)
{
Class boundType = null;
try
{
// namespace Class
boundType = Resources.classForName(namespace);
}
catch(ClassNotFoundException e) { }
if(boundType != null && !configuration.hasMapper(boundType))
{
//configuration, , loadedResources Set
configuration.addLoadedResource((new StringBuilder()).append("namespace:").append(namespace).toString());
//
configuration.addMapper(boundType);
}
}
}
//configration、リソース を するloadedResourceのSetpublic void addLoadedResource(String resource)
{
loadedResources.add(resource);
}
//mapperRegistry、mapInterfaceを する public void addMapper(Class type)
{
mapperRegistry.addMapper(type);
}
//MapperRegistry public class MapperRegistry
{
private Configuration config;
private final Map knownMappers = new HashMap();
public MapperRegistry(Configuration config)
{
this.config = config;
}
public void addMapper(Class type)
{
boolean loadCompleted;
if(!type.isInterface())
break MISSING_BLOCK_LABEL_125;
if(hasMapper(type))
throw new BindingException((new StringBuilder()).append("Type ").append(type).append(" is already known to the MapperRegistry.").toString());
loadCompleted = false;
knownMappers.put(type, new MapperProxyFactory(type));
// mapInterface,Class config MapperAnnotationBuilder
MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
parser.parse();
loadCompleted = true;
if(!loadCompleted)
knownMappers.remove(type);
break MISSING_BLOCK_LABEL_125;
Exception exception;
exception;
if(!loadCompleted)
knownMappers.remove(type);
throw exception;
}
}
//MapperRegistrypublic class MapperRegistry
{ public void addMapper(Class type)
{
boolean loadCompleted;
if(!type.isInterface())
break MISSING_BLOCK_LABEL_125;
if(hasMapper(type))
throw new BindingException((new StringBuilder()).append("Type ").append(type).append(" is already known to the MapperRegistry.").toString());
loadCompleted = false;
// Class MapperProxyFactory
knownMappers.put(type, new MapperProxyFactory(type));
// Mapperclass Builder
MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
//
parser.parse();
loadCompleted = true;
if(!loadCompleted)
knownMappers.remove(type);
break MISSING_BLOCK_LABEL_125;
Exception exception;
exception;
if(!loadCompleted)
knownMappers.remove(type);
throw exception;
}
private Configuration config;
//HashMap
private final Map knownMappers = new HashMap();
}
//MapperProxyFactory,mapperInterface
public class MapperProxyFactory
{
public MapperProxyFactory(Class mapperInterface)
{
methodCache = new ConcurrentHashMap();
this.mapperInterface = mapperInterface;
}
protected Object newInstance(MapperProxy mapperProxy)
{
//
return Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] {
mapperInterface
}, mapperProxy);
}
public Object newInstance(SqlSession sqlSession)
{
MapperProxy mapperProxy = new MapperProxy(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
private final Class mapperInterface;
private Map methodCache;
}
//MapperProxypublic class MapperProxy
implements InvocationHandler, Serializable
{
public MapperProxy(SqlSession sqlSession, Class mapperInterface, Map methodCache)
{
this.sqlSession = sqlSession;
this.mapperInterface = mapperInterface;
this.methodCache = methodCache;
}
public Object invoke(Object proxy, Method method, Object args[])
throws Throwable
{
if(java/lang/Object.equals(method.getDeclaringClass()))
{
return method.invoke(this, args);
} else
{
MapperMethod mapperMethod = cachedMapperMethod(method);
return mapperMethod.execute(sqlSession, args);
}
}
private MapperMethod cachedMapperMethod(Method method)
{
MapperMethod mapperMethod = (MapperMethod)methodCache.get(method);
if(mapperMethod == null)
{
mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration());
methodCache.put(method, mapperMethod);
}
return mapperMethod;
}
private static final long serialVersionUID = -6424540398559729838L;
private final SqlSession sqlSession;
private final Class mapperInterface;
//Map,
private final Map methodCache;
}
//MapperMethodpublic class MapperMethod
{
//
public static class MethodSignature{
private final boolean returnsMany;
private final boolean returnsMap;
private final boolean returnsVoid;
private final Class returnType;
private final String mapKey;
private final Integer resultHandlerIndex;
private final Integer rowBoundsIndex;
private final SortedMap params;
private final boolean hasNamedParameters;
public MethodSignature(Configuration configuration, Method method)
throws BindingException
{
returnType = method.getReturnType();
returnsVoid = Void.TYPE.equals(returnType);
returnsMany = configuration.getObjectFactory().isCollection(returnType) || returnType.isArray();
mapKey = getMapKey(method);
returnsMap = mapKey != null;
hasNamedParameters = hasNamedParams(method);
rowBoundsIndex = getUniqueParamIndex(method, org/apache/ibatis/session/RowBounds);
resultHandlerIndex = getUniqueParamIndex(method, org/apache/ibatis/session/ResultHandler);
params = Collections.unmodifiableSortedMap(getParams(method, hasNamedParameters));
}
}
//statement ,SqlCommand
public static class SqlCommand
{
private final String name;
private final SqlCommandType type;
}
// Map
public static class ParamMap extends HashMap
{
public Object get(Object key)
{
if(!super.containsKey(key))
throw new BindingException((new StringBuilder()).append("Parameter '").append(key).append("' not found. Available parameters are ").append(keySet()).toString());
else
return super.get(key);
}
private static final long serialVersionUID = -2212268410512043556L;
public ParamMap()
{
}
}
//method
public Object execute(SqlSession sqlSession, Object args[])
{
Object result;
//
if(SqlCommandType.INSERT == command.getType())
{
// SqlCommand
Object param = method.convertArgsToSqlCommandParam(args);
// ,
result = rowCountResult(sqlSession.insert(command.getName(), param));
} else
//
if(SqlCommandType.UPDATE == command.getType())
{
// ,
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.update(command.getName(), param));
} else
//
if(SqlCommandType.DELETE == command.getType())
{
// ,
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.delete(command.getName(), param));
} else
//
if(SqlCommandType.SELECT == command.getType())
{
if(method.returnsVoid() && method.hasResultHandler())
{
//
executeWithResultHandler(sqlSession, args);
result = null;
} else
if(method.returnsMany())
// List
result = executeForMany(sqlSession, args);
else
if(method.returnsMap())
{
// Map
result = executeForMap(sqlSession, args);
} else
{
// Object
Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(command.getName(), param);
}
} else
{
throw new BindingException((new StringBuilder()).append("Unknown execution method for: ").append(command.getName()).toString());
}
if(result == null && method.getReturnType().isPrimitive() && !method.returnsVoid())
throw new BindingException((new StringBuilder()).append("Mapper method '").append(command.getName()).append(" attempted to return null from a method with a primitive return type (").append(method.getReturnType()).append(").").toString());
else
return result;
}
//
private Object rowCountResult(int rowCount)
{
Object result;
if(method.returnsVoid())
result = null;
else
if(java/lang/Integer.equals(method.getReturnType()) || Integer.TYPE.equals(method.getReturnType()))
result = Integer.valueOf(rowCount);
else
if(java/lang/Long.equals(method.getReturnType()) || Long.TYPE.equals(method.getReturnType()))
result = Long.valueOf(rowCount);
else
if(java/lang/Boolean.equals(method.getReturnType()) || Boolean.TYPE.equals(method.getReturnType()))
result = Boolean.valueOf(rowCount > 0);
else
throw new BindingException((new StringBuilder()).append("Mapper method '").append(command.getName()).append("' has an unsupported return type: ").append(method.getReturnType()).toString());
return result;
}
//
private void executeWithResultHandler(SqlSession sqlSession, Object args[])
{
MappedStatement ms = sqlSession.getConfiguration().getMappedStatement(command.getName());
if(Void.TYPE.equals(((ResultMap)ms.getResultMaps().get(0)).getType()))
throw new BindingException((new StringBuilder()).append("method ").append(command.getName()).append(" needs either a @ResultMap annotation, a @ResultType annotation,").append(" or a resultType attribute in XML so a ResultHandler can be used as a parameter.").toString());
Object param = method.convertArgsToSqlCommandParam(args);
if(method.hasRowBounds())
{
RowBounds rowBounds = method.extractRowBounds(args);
sqlSession.select(command.getName(), param, rowBounds, method.extractResultHandler(args));
} else
{
sqlSession.select(command.getName(), param, method.extractResultHandler(args));
}
}
// List
private Object executeForMany(SqlSession sqlSession, Object args[])
{
Object param = method.convertArgsToSqlCommandParam(args);
List result;
if(method.hasRowBounds())
{
RowBounds rowBounds = method.extractRowBounds(args);
result = sqlSession.selectList(command.getName(), param, rowBounds);
} else
{
result = sqlSession.selectList(command.getName(), param);
}
if(!method.getReturnType().isAssignableFrom(result.getClass()))
{
if(method.getReturnType().isArray())
return ((Object) (convertToArray(result)));
else
return convertToDeclaredCollection(sqlSession.getConfiguration(), result);
} else
{
return result;
}
}
// Map
private Map executeForMap(SqlSession sqlSession, Object args[])
{
Object param = method.convertArgsToSqlCommandParam(args);
Map result;
if(method.hasRowBounds())
{
RowBounds rowBounds = method.extractRowBounds(args);
result = sqlSession.selectMap(command.getName(), param, method.getMapKey(), rowBounds);
} else
{
result = sqlSession.selectMap(command.getName(), param, method.getMapKey());
}
return result;
}
private final SqlCommand command;//method, statement
private final MethodSignature method;//
}
から るとConfigrationにMapperInterfaceを すると、MapperRegistryが されています。
HashMapでは、Mapper ProxyFactoryがMapper Interfaceの です。
MapperInterfaceを するMapperProxyの であり、MapperProxyではMapを し、
キャッシュを します。MapperInterfaceがDMLを するのは、MapperProxyの により、MapperMethodを び す です。
//Resourcepublic class Resources
{
public static Class classForName(String className)
throws ClassNotFoundException
{
return classLoaderWrapper.classForName(className);
}
private static ClassLoaderWrapper classLoaderWrapper = new ClassLoaderWrapper();
private static Charset charset;
}
//configrationから のResultMapsを する
parsePendingResultMaps();private void parsePendingResultMaps()
{
Collection incompleteResultMaps = configuration.getIncompleteResultMaps();
synchronized(incompleteResultMaps)
{
for(Iterator iter = incompleteResultMaps.iterator(); iter.hasNext();)
try
{
// ResultMap extend
((ResultMapResolver)iter.next()).resolve();
// configuration IncompleteResultMap
iter.remove();
}
catch(IncompleteElementException e) { }
}
}
//configrationから のCacheRefsを り く
parsePendingChecefs()private void parsePendingChacheRefs()
{
Collection incompleteCacheRefs = configuration.getIncompleteCacheRefs();
synchronized(incompleteCacheRefs)
{
for(Iterator iter = incompleteCacheRefs.iterator(); iter.hasNext();)
try
{
//CacheRefResolver configuration ,
// IncompleteCacheRefs,LinkedList CacheRefResolver
((CacheRefResolver)iter.next()).resolveCacheRef();
iter.remove();
}
catch(IncompleteElementException e) { }
}
}
//configrationから のSttementsを する
parsePendingSttements()private void parsePendingStatements()
{
Collection incompleteStatements = configuration.getIncompleteStatements();
synchronized(incompleteStatements)
{
for(Iterator iter = incompleteStatements.iterator(); iter.hasNext();)
try
{
// statement , incompleteStatements,
((XMLStatementBuilder)iter.next()).parseStatementNode();
iter.remove();
}
catch(IncompleteElementException e) { }
}
}
まとめ:
Mapper のxmlファイルを すると、 には xmlのmapper Xnode、 にはnamespace 、cache、cache-ref、parameterMap、reult Map、sql、およびselerct insert udateサブノードまで、mapper Xnodeを したら、Maconderectが されます。そしてMapperの を びつけて、 に ったのは、ConfigrationのMapperRegistryを じてMapperRegistryに されたHashMap MapperProxyFactoryはMapperInterfaceのエージェントであり、MapperInterfaceのMapperProxyエージェントの を し、MapperProxyはMapper ProxyでMapを して、Mapper ProxyはMapを して、 にMapperProxyでキャッシュされます。MapperMethodを び す 。その 、 のResultMap、CacheRefs、Sttements タスクを し、 、configrationからIncompleReltMaps、CacheRefs、Sttements Paserからタスクを します。
まとめ:cache-ref: cache-refから、 に、cacheとcache-refの のマッピング をconfigrationに し、configrationからcachef Namespace のCacheを し、cache-refのcachef Namespaceに するキャッシュが しない 、Incomplectement Emplectrotionをスローします。そして するCacheRefResoliverをconfigrationのIncompletCachef にLinklistに します。cache: の からCacheのノードの が られますが、 には、cacheノードのtypeに するクラス、cacheノードのevictに するキャッシュアルゴリズムClass、およびリフレッシュ 、 み き 、CacheBuiderを し、 されたconfigrationの2 キャッシュStrictMapを します。ParameterMap: の からParameterMapの は にParameterMapのid、type とparameterサブノードを することであることが かります。その 、parameterのproperty、javaType、jdbcType、typeHalder、reultMapの を し、これらの に づいてparameterMappingを し、 されたparameterMappings(ArayList)の において; にid、type とparameterMappingsに づいて、ParameterMapを し、configrationのparameterMapsに します。resultMap: の から、resultMapノードの が かります。まず、result Mapのid、typeなどの を して、サブノードのresult、construct、discriminatorを します。resultノードに して、column、property、jdbcTypeなどの を して、ResultMappingに して、result Mappings の でArayListを します。 に、resultMapのid、typeなどの とresultMappingsによってResultMapを し、extedの ResultMapが しない は、Incompplete Element Exceptionを り し、configrationに し、IncompleeteResultMap-linkedListに すれば、 されたMagults。Sql: から SqlノードはSqlノードをXnodeとidマッピング に させてsql Frame nts-HashMapに することであることが かります。select_insert_udate_delete: から かるように、select_insert_124を して、delete-Xnodeの を します。まず、ノード をXMLStatement Buiderに して、XMLSTAtementBuiderによって、 します。XMLStatement BuiderをconfigurationのIncompletSttement に し、Linked List;キャッシュ が されたら、SelectKeyノード とSelectKeyノードの を して、keySttementを し、configrationのmapped SttementのMapに して、Mapは、keySttementに づいてSelectKeyGeneratorを し、configrationのkeyGenerationのkeyGenerators-Mapに して、ノードがない は、Sectry Sectlecty Sectryは、ノードなし。statementノードのuseGenerate edKeys とグローバルプロファイル isUseGeneratodKeysとSql Command Type.INSERTによって するKeyGeneratorが される。statementノードとKeyGeneratorによって、MapperStatimentを し、configrationのmapped SttementのMapに します。
//Sql CommundTypepublic final class SqlCommandType extends Enum
{
public static final SqlCommandType UNKNOWN;
public static final SqlCommandType INSERT;
public static final SqlCommandType UPDATE;
public static final SqlCommandType DELETE;
public static final SqlCommandType SELECT;
private static final SqlCommandType $VALUES[];
static
{
UNKNOWN = new SqlCommandType("UNKNOWN", 0);
INSERT = new SqlCommandType("INSERT", 1);
UPDATE = new SqlCommandType("UPDATE", 2);
DELETE = new SqlCommandType("DELETE", 3);
SELECT = new SqlCommandType("SELECT", 4);
$VALUES = (new SqlCommandType[] {
UNKNOWN, INSERT, UPDATE, DELETE, SELECT
});
}
}
//Sttement Typespublic final class StatementType extends Enum
{
public static final StatementType STATEMENT;
public static final StatementType PREPARED;
public static final StatementType CALLABLE;
private static final StatementType $VALUES[];
static
{
STATEMENT = new StatementType("STATEMENT", 0);
PREPARED = new StatementType("PREPARED", 1);
CALLABLE = new StatementType("CALLABLE", 2);
$VALUES = (new StatementType[] {
STATEMENT, PREPARED, CALLABLE
});
}
}