获取mybatis-config.xml文件
加载mybatis-config.xml配置文件
对mybatis-config.xml文件进行解析
private void parseConfiguration(XNode root) { try { //获取Properties标签中的内容 this.propertiesElement(root.evalNode("properties")); //获取缓存 Properties settings = this.settingsAsProperties(root.evalNode("settings")); this.loadCustomVfs(settings); //加载别名 this.typeAliasesElement(root.evalNode("typeAliases")); //加载拦截器 this.pluginElement(root.evalNode("plugins")); //用于加载对象工厂(用于创建对象的实例) this.objectFactoryElement(root.evalNode("objectFactory")); //用于加载对象包装工程 this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); //用于反射实体类中的属性字段 this.reflectorFactoryElement(root.evalNode("reflectorFactory")); this.settingsElement(settings); //加载数据源 this.environmentsElement(root.evalNode("environments")); this.databaseIdProviderElement(root.evalNode("databaseIdProvider")); //用于实现JDBC和JAVA类型之间的转换 this.typeHandlerElement(root.evalNode("typeHandlers")); //加载Mappers标签中的内容,也就是写SQL语句的位置 this.mapperElement(root.evalNode("mappers")); } catch (Exception var3) { throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3); } }加载数据源
private void environmentsElement(XNode context) throws Exception { if (context != null) { if (this.environment == null) { this.environment = context.getStringAttribute("default"); } Iterator var2 = context.getChildren().iterator(); while(var2.hasNext()) { XNode child = (XNode)var2.next(); String id = child.getStringAttribute("id"); if (this.isSpecifiedEnvironment(id)) { TransactionFactory txFactory = this.transactionManagerElement(child.evalNode("transactionManager")); //下面这个方法会对数据源进行解析 DataSourceFactory dsFactory = this.dataSourceElement(child.evalNode("dataSource")); //获取到数据源 DataSource dataSource = dsFactory.getDataSource(); Builder environmentBuilder = (new Builder(id)).transactionFactory(txFactory).dataSource(dataSource); this.configuration.setEnvironment(environmentBuilder.build()); } } } }解析数据源
private DataSourceFactory dataSourceElement(XNode context) throws Exception { if (context != null) { //获取dataSource标签的一个类型 String type = context.getStringAttribute("type"); //取出数据源,Driver、URL、Username、Password Properties props = context.getChildrenAsProperties(); //通过反射的形式来获取对应的工厂实例 DataSourceFactory factory = (DataSourceFactory)this.resolveClass(type).newInstance(); factory.setProperties(props); return factory; } else { throw new BuilderException("Environment declaration requires a DataSourceFactory."); } }加载数据源会放在这个类中,包括了连接的最大数量、最小数量、过期时间等
解析Mapper的加载方式
private void mapperElement(XNode parent) throws Exception { /** * parent的内容是Mappers标签中的内容(包括了Mappers标签) * <mappers> * <mapper resource="mapper/ExJobMapper.xml"/> * </mappers> */ if (parent != null) { Iterator var2 = parent.getChildren().iterator(); while(true) { while(var2.hasNext()) { XNode child = (XNode)var2.next(); String resource; //判断Mappers的加载方式是否为Package,优先判断 if ("package".equals(child.getName())) { resource = child.getStringAttribute("name"); this.configuration.addMappers(resource); } else { resource = child.getStringAttribute("resource"); String url = child.getStringAttribute("url"); String mapperClass = child.getStringAttribute("class"); XMLMapperBuilder mapperParser; InputStream inputStream; //判断加载方式是否为Resource if (resource != null && url == null && mapperClass == null) { ErrorContext.instance().resource(resource); inputStream = Resources.getResourceAsStream(resource); mapperParser = new XMLMapperBuilder(inputStream, this.configuration, resource, this.configuration.getSqlFragments()); mapperParser.parse(); //判断加载方式是否为URL } else if (resource == null && url != null && mapperClass == null) { ErrorContext.instance().resource(url); inputStream = Resources.getUrlAsStream(url); mapperParser = new XMLMapperBuilder(inputStream, this.configuration, url, this.configuration.getSqlFragments()); mapperParser.parse(); } else { //判断加载方式是否为Class加载 if (resource != null || url != null || mapperClass == null) { throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one."); } Class<?> mapperInterface = Resources.classForName(mapperClass); this.configuration.addMapper(mapperInterface); } } } return; } } }解析Mappers中的各种相关配置
private void configurationElement(XNode context) { try { //获取命名空间 String namespace = context.getStringAttribute("namespace"); if (namespace != null && !namespace.equals("")) { //设置命名空间 this.builderAssistant.setCurrentNamespace(namespace); //用于引用另一个缓存 this.cacheRefElement(context.evalNode("cache-ref")); //设置缓存(默认为一级缓存) this.cacheElement(context.evalNode("cache")); //关系映射,数据一一映射到实体类属性当中 this.parameterMapElement(context.evalNodes("/mapper/parameterMap")); this.resultMapElements(context.evalNodes("/mapper/resultMap")); //解析SQL语句 this.sqlElement(context.evalNodes("/mapper/sql")); //判断SQL语句是DQL还是DML this.buildStatementFromContext(context.evalNodes("select|insert|update|delete")); } else { throw new BuilderException("Mapper's namespace cannot be empty"); } } catch (Exception var3) { throw new BuilderException("Error parsing Mapper XML. The XML location is '" + this.resource + "'. Cause: " + var3, var3); } }解析Mappers中SQL标签的各种配置
public void parseStatementNode() { //获取SQL标签中的Id String id = this.context.getStringAttribute("id"); //数据库的ID String databaseId = this.context.getStringAttribute("databaseId"); if (this.databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) { Integer fetchSize = this.context.getIntAttribute("fetchSize"); Integer timeout = this.context.getIntAttribute("timeout"); String parameterMap = this.context.getStringAttribute("parameterMap"); String parameterType = this.context.getStringAttribute("parameterType"); Class<?> parameterTypeClass = this.resolveClass(parameterType); String resultMap = this.context.getStringAttribute("resultMap"); String resultType = this.context.getStringAttribute("resultType"); String lang = this.context.getStringAttribute("lang"); LanguageDriver langDriver = this.getLanguageDriver(lang); Class<?> resultTypeClass = this.resolveClass(resultType); String resultSetType = this.context.getStringAttribute("resultSetType"); StatementType statementType = StatementType.valueOf(this.context.getStringAttribute("statementType", StatementType.PREPARED.toString())); ResultSetType resultSetTypeEnum = this.resolveResultSetType(resultSetType); //获取标签头(例如SELECT、DELETE、UPDATE、INSERT) String nodeName = this.context.getNode().getNodeName(); SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH)); boolean isSelect = sqlCommandType == SqlCommandType.SELECT; boolean flushCache = this.context.getBooleanAttribute("flushCache", !isSelect); boolean useCache = this.context.getBooleanAttribute("useCache", isSelect); boolean resultOrdered = this.context.getBooleanAttribute("resultOrdered", false); XMLIncludeTransformer includeParser = new XMLIncludeTransformer(this.configuration, this.builderAssistant); includeParser.applyIncludes(this.context.getNode()); this.processSelectKeyNodes(id, parameterTypeClass, langDriver); //获取到完整的一条SQL语句 SqlSource sqlSource = langDriver.createSqlSource(this.configuration, this.context, parameterTypeClass); String resultSets = this.context.getStringAttribute("resultSets"); String keyProperty = this.context.getStringAttribute("keyProperty"); String keyColumn = this.context.getStringAttribute("keyColumn"); String keyStatementId = id + "!selectKey"; keyStatementId = this.builderAssistant.applyCurrentNamespace(keyStatementId, true); Object keyGenerator; if (this.configuration.hasKeyGenerator(keyStatementId)) { keyGenerator = this.configuration.getKeyGenerator(keyStatementId); } else { keyGenerator = this.context.getBooleanAttribute("useGeneratedKeys", this.configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType)) ? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE; } this.builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache, resultOrdered, (KeyGenerator)keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets); } }将加载好的结果存放在该类中并且返回