Jelajahi Sumber

原生加载顺序调整

Caratacus 8 tahun lalu
induk
melakukan
c444720d64

+ 1 - 1
mybatis-plus/pom.xml

@@ -37,7 +37,7 @@
         <slf4j.version>1.7.21</slf4j.version>
         <logback-classic.version>1.1.7</logback-classic.version>
         <mysql-connector-java.version>5.1.38</mysql-connector-java.version>
-        <ojdbc14.version>10.2.0.5.0</ojdbc14.version>
+        <ojdbc14.version>10.2.0.4.0</ojdbc14.version>
         <servlet-api.version>2.5</servlet-api.version>
         <spring.version>4.2.5.RELEASE</spring.version>
         <mybatis-ehcache.version>1.0.3</mybatis-ehcache.version>

+ 371 - 354
mybatis-plus/src/main/java/com/baomidou/mybatisplus/MybatisXMLConfigBuilder.java

@@ -1,12 +1,12 @@
 /**
  * Copyright (c) 2011-2014, hubin (jobob@qq.com).
- *
+ * <p>
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- *
+ * <p>
  * http://www.apache.org/licenses/LICENSE-2.0
- *
+ * <p>
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -45,6 +45,8 @@ import org.apache.ibatis.type.JdbcType;
 import javax.sql.DataSource;
 import java.io.InputStream;
 import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Properties;
 
 /**
@@ -58,356 +60,371 @@ import java.util.Properties;
  */
 public class MybatisXMLConfigBuilder extends BaseBuilder {
 
-	private boolean parsed;
-	private XPathParser parser;
-	private String environment;
-	private ReflectorFactory localReflectorFactory = new DefaultReflectorFactory();
-
-	public MybatisXMLConfigBuilder(Reader reader) {
-		this(reader, null, null);
-	}
-
-	public MybatisXMLConfigBuilder(Reader reader, String environment) {
-		this(reader, environment, null);
-	}
-
-	public MybatisXMLConfigBuilder(Reader reader, String environment, Properties props) {
-		this(new XPathParser(reader, true, props, new XMLMapperEntityResolver()), environment, props);
-	}
-
-	public MybatisXMLConfigBuilder(InputStream inputStream) {
-		this(inputStream, null, null);
-	}
-
-	public MybatisXMLConfigBuilder(InputStream inputStream, String environment) {
-		this(inputStream, environment, null);
-	}
-
-	public MybatisXMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
-		this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);
-	}
-
-	private MybatisXMLConfigBuilder(XPathParser parser, String environment, Properties props) {
-		//TODO 自定义 Configuration
-		super(new MybatisConfiguration());
-		ErrorContext.instance().resource("SQL Mapper Configuration");
-		this.configuration.setVariables(props);
-		this.parsed = false;
-		this.environment = environment;
-		this.parser = parser;
-	}
-
-	public Configuration parse() {
-		if (parsed) {
-			throw new BuilderException("Each XMLConfigBuilder can only be used once.");
-		}
-		parsed = true;
-		parseConfiguration(parser.evalNode("/configuration"));
-		return configuration;
-	}
-
-	private void parseConfiguration(XNode root) {
-		try {
-			Properties settings = settingsAsPropertiess(root.evalNode("settings"));
-			// issue #117 read properties first
-			propertiesElement(root.evalNode("properties"));
-			loadCustomVfs(settings);
-			typeAliasesElement(root.evalNode("typeAliases"));
-			pluginElement(root.evalNode("plugins"));
-			objectFactoryElement(root.evalNode("objectFactory"));
-			objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
-			reflectorFactoryElement(root.evalNode("reflectorFactory"));
-			settingsElement(settings);
-			// read it after objectFactory and objectWrapperFactory issue #631
-			environmentsElement(root.evalNode("environments"));
-			databaseIdProviderElement(root.evalNode("databaseIdProvider"));
-			typeHandlerElement(root.evalNode("typeHandlers"));
-			mapperElement(root.evalNode("mappers"));
-		} catch (Exception e) {
-			throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
-		}
-	}
-
-	private Properties settingsAsPropertiess(XNode context) {
-		if (context == null) {
-			return new Properties();
-		}
-		Properties props = context.getChildrenAsProperties();
-		// Check that all settings are known to the configuration class
-		MetaClass metaConfig = MetaClass.forClass(Configuration.class, localReflectorFactory);
-		for (Object key : props.keySet()) {
-			if (!metaConfig.hasSetter(String.valueOf(key))) {
-				throw new BuilderException(
-						"The setting " + key + " is not known.  Make sure you spelled it correctly (case sensitive).");
-			}
-		}
-		return props;
-	}
-
-	private void loadCustomVfs(Properties props) throws ClassNotFoundException {
-		String value = props.getProperty("vfsImpl");
-		if (value != null) {
-			String[] clazzes = value.split(",");
-			for (String clazz : clazzes) {
-				if (!clazz.isEmpty()) {
-					@SuppressWarnings("unchecked")
-					Class<? extends VFS> vfsImpl = (Class<? extends VFS>) Resources.classForName(clazz);
-					configuration.setVfsImpl(vfsImpl);
-				}
-			}
-		}
-	}
-
-	private void typeAliasesElement(XNode parent) {
-		if (parent != null) {
-			for (XNode child : parent.getChildren()) {
-				if ("package".equals(child.getName())) {
-					String typeAliasPackage = child.getStringAttribute("name");
-					configuration.getTypeAliasRegistry().registerAliases(typeAliasPackage);
-				} else {
-					String alias = child.getStringAttribute("alias");
-					String type = child.getStringAttribute("type");
-					try {
-						Class<?> clazz = Resources.classForName(type);
-						if (alias == null) {
-							typeAliasRegistry.registerAlias(clazz);
-						} else {
-							typeAliasRegistry.registerAlias(alias, clazz);
-						}
-					} catch (ClassNotFoundException e) {
-						throw new BuilderException("Error registering typeAlias for '" + alias + "'. Cause: " + e, e);
-					}
-				}
-			}
-		}
-	}
-
-	private void pluginElement(XNode parent) throws Exception {
-		if (parent != null) {
-			for (XNode child : parent.getChildren()) {
-				String interceptor = child.getStringAttribute("interceptor");
-				Properties properties = child.getChildrenAsProperties();
-				Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).newInstance();
-				interceptorInstance.setProperties(properties);
-				configuration.addInterceptor(interceptorInstance);
-			}
-		}
-	}
-
-	private void objectFactoryElement(XNode context) throws Exception {
-		if (context != null) {
-			String type = context.getStringAttribute("type");
-			Properties properties = context.getChildrenAsProperties();
-			ObjectFactory factory = (ObjectFactory) resolveClass(type).newInstance();
-			factory.setProperties(properties);
-			configuration.setObjectFactory(factory);
-		}
-	}
-
-	private void objectWrapperFactoryElement(XNode context) throws Exception {
-		if (context != null) {
-			String type = context.getStringAttribute("type");
-			ObjectWrapperFactory factory = (ObjectWrapperFactory) resolveClass(type).newInstance();
-			configuration.setObjectWrapperFactory(factory);
-		}
-	}
-
-	private void reflectorFactoryElement(XNode context) throws Exception {
-		if (context != null) {
-			String type = context.getStringAttribute("type");
-			ReflectorFactory factory = (ReflectorFactory) resolveClass(type).newInstance();
-			configuration.setReflectorFactory(factory);
-		}
-	}
-
-	private void propertiesElement(XNode context) throws Exception {
-		if (context != null) {
-			Properties defaults = context.getChildrenAsProperties();
-			String resource = context.getStringAttribute("resource");
-			String url = context.getStringAttribute("url");
-			if (resource != null && url != null) {
-				throw new BuilderException(
-						"The properties element cannot specify both a URL and a resource based property file reference.  Please specify one or the other.");
-			}
-			if (resource != null) {
-				defaults.putAll(Resources.getResourceAsProperties(resource));
-			} else if (url != null) {
-				defaults.putAll(Resources.getUrlAsProperties(url));
-			}
-			Properties vars = configuration.getVariables();
-			if (vars != null) {
-				defaults.putAll(vars);
-			}
-			parser.setVariables(defaults);
-			configuration.setVariables(defaults);
-		}
-	}
-
-	private void settingsElement(Properties props) throws Exception {
-		configuration.setAutoMappingBehavior(
-				AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior", "PARTIAL")));
-		configuration.setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior
-				.valueOf(props.getProperty("autoMappingUnknownColumnBehavior", "NONE")));
-		configuration.setCacheEnabled(booleanValueOf(props.getProperty("cacheEnabled"), true));
-		configuration.setProxyFactory((ProxyFactory) createInstance(props.getProperty("proxyFactory")));
-		configuration.setLazyLoadingEnabled(booleanValueOf(props.getProperty("lazyLoadingEnabled"), false));
-		configuration.setAggressiveLazyLoading(booleanValueOf(props.getProperty("aggressiveLazyLoading"), true));
-		configuration
-				.setMultipleResultSetsEnabled(booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true));
-		configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), true));
-		configuration.setUseGeneratedKeys(booleanValueOf(props.getProperty("useGeneratedKeys"), false));
-		configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE")));
-		configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null));
-		configuration.setDefaultFetchSize(integerValueOf(props.getProperty("defaultFetchSize"), null));
-		configuration.setMapUnderscoreToCamelCase(booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), false));
-		configuration.setSafeRowBoundsEnabled(booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false));
-		configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope", "SESSION")));
-		configuration.setJdbcTypeForNull(JdbcType.valueOf(props.getProperty("jdbcTypeForNull", "OTHER")));
-		configuration.setLazyLoadTriggerMethods(
-				stringSetValueOf(props.getProperty("lazyLoadTriggerMethods"), "equals,clone,hashCode,toString"));
-		configuration.setSafeResultHandlerEnabled(booleanValueOf(props.getProperty("safeResultHandlerEnabled"), true));
-		configuration.setDefaultScriptingLanguage(resolveClass(props.getProperty("defaultScriptingLanguage")));
-		configuration.setCallSettersOnNulls(booleanValueOf(props.getProperty("callSettersOnNulls"), false));
-		configuration.setUseActualParamName(booleanValueOf(props.getProperty("useActualParamName"), false));
-		configuration.setLogPrefix(props.getProperty("logPrefix"));
-		@SuppressWarnings("unchecked")
-		Class<? extends Log> logImpl = (Class<? extends Log>) resolveClass(props.getProperty("logImpl"));
-		configuration.setLogImpl(logImpl);
-		configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory")));
-	}
-
-	private void environmentsElement(XNode context) throws Exception {
-		if (context != null) {
-			if (environment == null) {
-				environment = context.getStringAttribute("default");
-			}
-			for (XNode child : context.getChildren()) {
-				String id = child.getStringAttribute("id");
-				if (isSpecifiedEnvironment(id)) {
-					TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
-					DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
-					DataSource dataSource = dsFactory.getDataSource();
-					Environment.Builder environmentBuilder = new Environment.Builder(id).transactionFactory(txFactory)
-							.dataSource(dataSource);
-					configuration.setEnvironment(environmentBuilder.build());
-				}
-			}
-		}
-	}
-
-	private void databaseIdProviderElement(XNode context) throws Exception {
-		DatabaseIdProvider databaseIdProvider = null;
-		if (context != null) {
-			String type = context.getStringAttribute("type");
-			// awful patch to keep backward compatibility
-			if ("VENDOR".equals(type)) {
-				type = "DB_VENDOR";
-			}
-			Properties properties = context.getChildrenAsProperties();
-			databaseIdProvider = (DatabaseIdProvider) resolveClass(type).newInstance();
-			databaseIdProvider.setProperties(properties);
-		}
-		Environment environment = configuration.getEnvironment();
-		if (environment != null && databaseIdProvider != null) {
-			String databaseId = databaseIdProvider.getDatabaseId(environment.getDataSource());
-			configuration.setDatabaseId(databaseId);
-		}
-	}
-
-	private TransactionFactory transactionManagerElement(XNode context) throws Exception {
-		if (context != null) {
-			String type = context.getStringAttribute("type");
-			Properties props = context.getChildrenAsProperties();
-			TransactionFactory factory = (TransactionFactory) resolveClass(type).newInstance();
-			factory.setProperties(props);
-			return factory;
-		}
-		throw new BuilderException("Environment declaration requires a TransactionFactory.");
-	}
-
-	private DataSourceFactory dataSourceElement(XNode context) throws Exception {
-		if (context != null) {
-			String type = context.getStringAttribute("type");
-			Properties props = context.getChildrenAsProperties();
-			DataSourceFactory factory = (DataSourceFactory) resolveClass(type).newInstance();
-			factory.setProperties(props);
-			return factory;
-		}
-		throw new BuilderException("Environment declaration requires a DataSourceFactory.");
-	}
-
-	private void typeHandlerElement(XNode parent) throws Exception {
-		if (parent != null) {
-			for (XNode child : parent.getChildren()) {
-				if ("package".equals(child.getName())) {
-					String typeHandlerPackage = child.getStringAttribute("name");
-					typeHandlerRegistry.register(typeHandlerPackage);
-				} else {
-					String javaTypeName = child.getStringAttribute("javaType");
-					String jdbcTypeName = child.getStringAttribute("jdbcType");
-					String handlerTypeName = child.getStringAttribute("handler");
-					Class<?> javaTypeClass = resolveClass(javaTypeName);
-					JdbcType jdbcType = resolveJdbcType(jdbcTypeName);
-					Class<?> typeHandlerClass = resolveClass(handlerTypeName);
-					if (javaTypeClass != null) {
-						if (jdbcType == null) {
-							typeHandlerRegistry.register(javaTypeClass, typeHandlerClass);
-						} else {
-							typeHandlerRegistry.register(javaTypeClass, jdbcType, typeHandlerClass);
-						}
-					} else {
-						typeHandlerRegistry.register(typeHandlerClass);
-					}
-				}
-			}
-		}
-	}
-
-	private void mapperElement(XNode parent) throws Exception {
-		if (parent != null) {
-			for (XNode child : parent.getChildren()) {
-				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");
-					if (resource != null && url == null && mapperClass == null) {
-						ErrorContext.instance().resource(resource);
-						InputStream inputStream = Resources.getResourceAsStream(resource);
-						//TODO
-						MybatisXMLMapperBuilder mapperParser = new MybatisXMLMapperBuilder(inputStream, configuration, resource,
-								configuration.getSqlFragments());
-						mapperParser.parse();
-					} else if (resource == null && url != null && mapperClass == null) {
-						ErrorContext.instance().resource(url);
-						InputStream inputStream = Resources.getUrlAsStream(url);
-						//TODO
-						MybatisXMLMapperBuilder mapperParser = new MybatisXMLMapperBuilder(inputStream, configuration, url,
-								configuration.getSqlFragments());
-						mapperParser.parse();
-					} else if (resource == null && url == null && mapperClass != null) {
-						Class<?> mapperInterface = Resources.classForName(mapperClass);
-						configuration.addMapper(mapperInterface);
-					} else {
-						throw new BuilderException(
-								"A mapper element may only specify a url, resource or class, but not more than one.");
-					}
-				}
-			}
-		}
-	}
-
-	private boolean isSpecifiedEnvironment(String id) {
-		if (environment == null) {
-			throw new BuilderException("No environment specified.");
-		} else if (id == null) {
-			throw new BuilderException("Environment requires an id attribute.");
-		} else if (environment.equals(id)) {
-			return true;
-		}
-		return false;
-	}
+    private boolean parsed;
+    private XPathParser parser;
+    private String environment;
+    private ReflectorFactory localReflectorFactory = new DefaultReflectorFactory();
+
+    public MybatisXMLConfigBuilder(Reader reader) {
+        this(reader, null, null);
+    }
+
+    public MybatisXMLConfigBuilder(Reader reader, String environment) {
+        this(reader, environment, null);
+    }
+
+    public MybatisXMLConfigBuilder(Reader reader, String environment, Properties props) {
+        this(new XPathParser(reader, true, props, new XMLMapperEntityResolver()), environment, props);
+    }
+
+    public MybatisXMLConfigBuilder(InputStream inputStream) {
+        this(inputStream, null, null);
+    }
+
+    public MybatisXMLConfigBuilder(InputStream inputStream, String environment) {
+        this(inputStream, environment, null);
+    }
+
+    public MybatisXMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
+        this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);
+    }
+
+    private MybatisXMLConfigBuilder(XPathParser parser, String environment, Properties props) {
+        //TODO 自定义 Configuration
+        super(new MybatisConfiguration());
+        ErrorContext.instance().resource("SQL Mapper Configuration");
+        this.configuration.setVariables(props);
+        this.parsed = false;
+        this.environment = environment;
+        this.parser = parser;
+    }
+
+    public Configuration parse() {
+        if (parsed) {
+            throw new BuilderException("Each XMLConfigBuilder can only be used once.");
+        }
+        parsed = true;
+        parseConfiguration(parser.evalNode("/configuration"));
+        return configuration;
+    }
+
+    private void parseConfiguration(XNode root) {
+        try {
+            Properties settings = settingsAsPropertiess(root.evalNode("settings"));
+            // issue #117 read properties first
+            propertiesElement(root.evalNode("properties"));
+            loadCustomVfs(settings);
+            typeAliasesElement(root.evalNode("typeAliases"));
+            pluginElement(root.evalNode("plugins"));
+            objectFactoryElement(root.evalNode("objectFactory"));
+            objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
+            reflectorFactoryElement(root.evalNode("reflectorFactory"));
+            settingsElement(settings);
+            // read it after objectFactory and objectWrapperFactory issue #631
+            environmentsElement(root.evalNode("environments"));
+            databaseIdProviderElement(root.evalNode("databaseIdProvider"));
+            typeHandlerElement(root.evalNode("typeHandlers"));
+            mapperElement(root.evalNode("mappers"));
+        } catch (Exception e) {
+            throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
+        }
+    }
+
+    private Properties settingsAsPropertiess(XNode context) {
+        if (context == null) {
+            return new Properties();
+        }
+        Properties props = context.getChildrenAsProperties();
+        // Check that all settings are known to the configuration class
+        MetaClass metaConfig = MetaClass.forClass(Configuration.class, localReflectorFactory);
+        for (Object key : props.keySet()) {
+            if (!metaConfig.hasSetter(String.valueOf(key))) {
+                throw new BuilderException(
+                        "The setting " + key + " is not known.  Make sure you spelled it correctly (case sensitive).");
+            }
+        }
+        return props;
+    }
+
+    private void loadCustomVfs(Properties props) throws ClassNotFoundException {
+        String value = props.getProperty("vfsImpl");
+        if (value != null) {
+            String[] clazzes = value.split(",");
+            for (String clazz : clazzes) {
+                if (!clazz.isEmpty()) {
+                    @SuppressWarnings("unchecked")
+                    Class<? extends VFS> vfsImpl = (Class<? extends VFS>) Resources.classForName(clazz);
+                    configuration.setVfsImpl(vfsImpl);
+                }
+            }
+        }
+    }
+
+    private void typeAliasesElement(XNode parent) {
+        if (parent != null) {
+            for (XNode child : parent.getChildren()) {
+                if ("package".equals(child.getName())) {
+                    String typeAliasPackage = child.getStringAttribute("name");
+                    configuration.getTypeAliasRegistry().registerAliases(typeAliasPackage);
+                } else {
+                    String alias = child.getStringAttribute("alias");
+                    String type = child.getStringAttribute("type");
+                    try {
+                        Class<?> clazz = Resources.classForName(type);
+                        if (alias == null) {
+                            typeAliasRegistry.registerAlias(clazz);
+                        } else {
+                            typeAliasRegistry.registerAlias(alias, clazz);
+                        }
+                    } catch (ClassNotFoundException e) {
+                        throw new BuilderException("Error registering typeAlias for '" + alias + "'. Cause: " + e, e);
+                    }
+                }
+            }
+        }
+    }
+
+    private void pluginElement(XNode parent) throws Exception {
+        if (parent != null) {
+            for (XNode child : parent.getChildren()) {
+                String interceptor = child.getStringAttribute("interceptor");
+                Properties properties = child.getChildrenAsProperties();
+                Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).newInstance();
+                interceptorInstance.setProperties(properties);
+                configuration.addInterceptor(interceptorInstance);
+            }
+        }
+    }
+
+    private void objectFactoryElement(XNode context) throws Exception {
+        if (context != null) {
+            String type = context.getStringAttribute("type");
+            Properties properties = context.getChildrenAsProperties();
+            ObjectFactory factory = (ObjectFactory) resolveClass(type).newInstance();
+            factory.setProperties(properties);
+            configuration.setObjectFactory(factory);
+        }
+    }
+
+    private void objectWrapperFactoryElement(XNode context) throws Exception {
+        if (context != null) {
+            String type = context.getStringAttribute("type");
+            ObjectWrapperFactory factory = (ObjectWrapperFactory) resolveClass(type).newInstance();
+            configuration.setObjectWrapperFactory(factory);
+        }
+    }
+
+    private void reflectorFactoryElement(XNode context) throws Exception {
+        if (context != null) {
+            String type = context.getStringAttribute("type");
+            ReflectorFactory factory = (ReflectorFactory) resolveClass(type).newInstance();
+            configuration.setReflectorFactory(factory);
+        }
+    }
+
+    private void propertiesElement(XNode context) throws Exception {
+        if (context != null) {
+            Properties defaults = context.getChildrenAsProperties();
+            String resource = context.getStringAttribute("resource");
+            String url = context.getStringAttribute("url");
+            if (resource != null && url != null) {
+                throw new BuilderException(
+                        "The properties element cannot specify both a URL and a resource based property file reference.  Please specify one or the other.");
+            }
+            if (resource != null) {
+                defaults.putAll(Resources.getResourceAsProperties(resource));
+            } else if (url != null) {
+                defaults.putAll(Resources.getUrlAsProperties(url));
+            }
+            Properties vars = configuration.getVariables();
+            if (vars != null) {
+                defaults.putAll(vars);
+            }
+            parser.setVariables(defaults);
+            configuration.setVariables(defaults);
+        }
+    }
+
+    private void settingsElement(Properties props) throws Exception {
+        configuration.setAutoMappingBehavior(
+                AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior", "PARTIAL")));
+        configuration.setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior
+                .valueOf(props.getProperty("autoMappingUnknownColumnBehavior", "NONE")));
+        configuration.setCacheEnabled(booleanValueOf(props.getProperty("cacheEnabled"), true));
+        configuration.setProxyFactory((ProxyFactory) createInstance(props.getProperty("proxyFactory")));
+        configuration.setLazyLoadingEnabled(booleanValueOf(props.getProperty("lazyLoadingEnabled"), false));
+        configuration.setAggressiveLazyLoading(booleanValueOf(props.getProperty("aggressiveLazyLoading"), true));
+        configuration
+                .setMultipleResultSetsEnabled(booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true));
+        configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), true));
+        configuration.setUseGeneratedKeys(booleanValueOf(props.getProperty("useGeneratedKeys"), false));
+        configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE")));
+        configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null));
+        configuration.setDefaultFetchSize(integerValueOf(props.getProperty("defaultFetchSize"), null));
+        configuration.setMapUnderscoreToCamelCase(booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), false));
+        configuration.setSafeRowBoundsEnabled(booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false));
+        configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope", "SESSION")));
+        configuration.setJdbcTypeForNull(JdbcType.valueOf(props.getProperty("jdbcTypeForNull", "OTHER")));
+        configuration.setLazyLoadTriggerMethods(
+                stringSetValueOf(props.getProperty("lazyLoadTriggerMethods"), "equals,clone,hashCode,toString"));
+        configuration.setSafeResultHandlerEnabled(booleanValueOf(props.getProperty("safeResultHandlerEnabled"), true));
+        configuration.setDefaultScriptingLanguage(resolveClass(props.getProperty("defaultScriptingLanguage")));
+        configuration.setCallSettersOnNulls(booleanValueOf(props.getProperty("callSettersOnNulls"), false));
+        configuration.setUseActualParamName(booleanValueOf(props.getProperty("useActualParamName"), false));
+        configuration.setLogPrefix(props.getProperty("logPrefix"));
+        @SuppressWarnings("unchecked")
+        Class<? extends Log> logImpl = (Class<? extends Log>) resolveClass(props.getProperty("logImpl"));
+        configuration.setLogImpl(logImpl);
+        configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory")));
+    }
+
+    private void environmentsElement(XNode context) throws Exception {
+        if (context != null) {
+            if (environment == null) {
+                environment = context.getStringAttribute("default");
+            }
+            for (XNode child : context.getChildren()) {
+                String id = child.getStringAttribute("id");
+                if (isSpecifiedEnvironment(id)) {
+                    TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
+                    DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
+                    DataSource dataSource = dsFactory.getDataSource();
+                    Environment.Builder environmentBuilder = new Environment.Builder(id).transactionFactory(txFactory)
+                            .dataSource(dataSource);
+                    configuration.setEnvironment(environmentBuilder.build());
+                }
+            }
+        }
+    }
+
+    private void databaseIdProviderElement(XNode context) throws Exception {
+        DatabaseIdProvider databaseIdProvider = null;
+        if (context != null) {
+            String type = context.getStringAttribute("type");
+            // awful patch to keep backward compatibility
+            if ("VENDOR".equals(type)) {
+                type = "DB_VENDOR";
+            }
+            Properties properties = context.getChildrenAsProperties();
+            databaseIdProvider = (DatabaseIdProvider) resolveClass(type).newInstance();
+            databaseIdProvider.setProperties(properties);
+        }
+        Environment environment = configuration.getEnvironment();
+        if (environment != null && databaseIdProvider != null) {
+            String databaseId = databaseIdProvider.getDatabaseId(environment.getDataSource());
+            configuration.setDatabaseId(databaseId);
+        }
+    }
+
+    private TransactionFactory transactionManagerElement(XNode context) throws Exception {
+        if (context != null) {
+            String type = context.getStringAttribute("type");
+            Properties props = context.getChildrenAsProperties();
+            TransactionFactory factory = (TransactionFactory) resolveClass(type).newInstance();
+            factory.setProperties(props);
+            return factory;
+        }
+        throw new BuilderException("Environment declaration requires a TransactionFactory.");
+    }
+
+    private DataSourceFactory dataSourceElement(XNode context) throws Exception {
+        if (context != null) {
+            String type = context.getStringAttribute("type");
+            Properties props = context.getChildrenAsProperties();
+            DataSourceFactory factory = (DataSourceFactory) resolveClass(type).newInstance();
+            factory.setProperties(props);
+            return factory;
+        }
+        throw new BuilderException("Environment declaration requires a DataSourceFactory.");
+    }
+
+    private void typeHandlerElement(XNode parent) throws Exception {
+        if (parent != null) {
+            for (XNode child : parent.getChildren()) {
+                if ("package".equals(child.getName())) {
+                    String typeHandlerPackage = child.getStringAttribute("name");
+                    typeHandlerRegistry.register(typeHandlerPackage);
+                } else {
+                    String javaTypeName = child.getStringAttribute("javaType");
+                    String jdbcTypeName = child.getStringAttribute("jdbcType");
+                    String handlerTypeName = child.getStringAttribute("handler");
+                    Class<?> javaTypeClass = resolveClass(javaTypeName);
+                    JdbcType jdbcType = resolveJdbcType(jdbcTypeName);
+                    Class<?> typeHandlerClass = resolveClass(handlerTypeName);
+                    if (javaTypeClass != null) {
+                        if (jdbcType == null) {
+                            typeHandlerRegistry.register(javaTypeClass, typeHandlerClass);
+                        } else {
+                            typeHandlerRegistry.register(javaTypeClass, jdbcType, typeHandlerClass);
+                        }
+                    } else {
+                        typeHandlerRegistry.register(typeHandlerClass);
+                    }
+                }
+            }
+        }
+    }
+
+    private void mapperElement(XNode parent) throws Exception {
+        List<String> resources = new ArrayList<String>();
+        List<String> urls = new ArrayList<String>();
+        List<String> mapperClasses = new ArrayList<String>();
+        if (parent != null) {
+            for (XNode child : parent.getChildren()) {
+                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");
+                    if (resource != null && url == null && mapperClass == null) {
+                        resources.add(resource);
+                    } else if (resource == null && url != null && mapperClass == null) {
+                        urls.add(url);
+
+                    } else if (resource == null && url == null && mapperClass != null) {
+                        mapperClasses.add(mapperClass);
+
+                    } else {
+                        throw new BuilderException(
+                                "A mapper element may only specify a url, resource or class, but not more than one.");
+                    }
+                }
+            }
+            for (String url : urls) {
+                ErrorContext.instance().resource(url);
+                InputStream inputStream = Resources.getUrlAsStream(url);
+                //TODO
+                MybatisXMLMapperBuilder mapperParser = new MybatisXMLMapperBuilder(inputStream, configuration, url,
+                        configuration.getSqlFragments());
+                mapperParser.parse();
+            }
+            for (String resource : resources) {
+                ErrorContext.instance().resource(resource);
+                InputStream inputStream = Resources.getResourceAsStream(resource);
+                //TODO
+                MybatisXMLMapperBuilder mapperParser = new MybatisXMLMapperBuilder(inputStream, configuration, resource,
+                        configuration.getSqlFragments());
+                mapperParser.parse();
+            }
+            for (String mapper : mapperClasses) {
+                Class<?> mapperInterface = Resources.classForName(mapper);
+                configuration.addMapper(mapperInterface);
+            }
+
+        }
+    }
+
+    private boolean isSpecifiedEnvironment(String id) {
+        if (environment == null) {
+            throw new BuilderException("No environment specified.");
+        } else if (id == null) {
+            throw new BuilderException("Environment requires an id attribute.");
+        } else if (environment.equals(id)) {
+            return true;
+        }
+        return false;
+    }
 
 }

+ 2 - 1
mybatis-plus/src/test/resources/mysql-config.xml

@@ -103,9 +103,10 @@
      | package  指向可以找到Mapper接口的包名
      | -->
     <mappers>
-        <mapper resource="mysql/UserMapper.xml"/>
+
         <mapper resource="mysql/RoleMapper.xml"/>
         <mapper class="com.baomidou.mybatisplus.test.mysql.UserMapper" />
+        <mapper resource="mysql/UserMapper.xml"/>
         <mapper class="com.baomidou.mybatisplus.test.mysql.RoleMapper" />
         <mapper class="com.baomidou.mybatisplus.test.mysql.TestMapper" />
     </mappers>