Selaa lähdekoodia

MybatisXMLConfigBuilder 跟进mybatis

miemie 5 vuotta sitten
vanhempi
commit
494cc0446e

+ 1 - 2
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisSqlSessionFactoryBuilder.java

@@ -79,8 +79,7 @@ public class MybatisSqlSessionFactoryBuilder extends SqlSessionFactoryBuilder {
 
     // TODO 使用自己的逻辑,注入必须组件
     @Override
-    public SqlSessionFactory build(Configuration config) {
-        MybatisConfiguration configuration = (MybatisConfiguration) config;
+    public SqlSessionFactory build(Configuration configuration) {
         GlobalConfig globalConfig = GlobalConfigUtils.getGlobalConfig(configuration);
         final IdentifierGenerator identifierGenerator;
         if (globalConfig.getIdentifierGenerator() == null) {

+ 41 - 80
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisXMLConfigBuilder.java

@@ -23,7 +23,6 @@ import org.apache.ibatis.builder.xml.XMLMapperEntityResolver;
 import org.apache.ibatis.datasource.DataSourceFactory;
 import org.apache.ibatis.executor.ErrorContext;
 import org.apache.ibatis.executor.loader.ProxyFactory;
-import org.apache.ibatis.io.ResolverUtil;
 import org.apache.ibatis.io.Resources;
 import org.apache.ibatis.io.VFS;
 import org.apache.ibatis.logging.Log;
@@ -44,9 +43,7 @@ import org.apache.ibatis.type.JdbcType;
 import javax.sql.DataSource;
 import java.io.InputStream;
 import java.io.Reader;
-import java.util.HashSet;
 import java.util.Properties;
-import java.util.Set;
 
 /**
  * 从 {@link XMLConfigBuilder} copy 过来, 使用自己的 MybatisConfiguration 而不是 Configuration
@@ -56,10 +53,10 @@ import java.util.Set;
  */
 public class MybatisXMLConfigBuilder extends BaseBuilder {
 
-    private final XPathParser parser;
-    private final ReflectorFactory localReflectorFactory = new DefaultReflectorFactory();
     private boolean parsed;
+    private final XPathParser parser;
     private String environment;
+    private final ReflectorFactory localReflectorFactory = new DefaultReflectorFactory();
 
     public MybatisXMLConfigBuilder(Reader reader) {
         this(reader, null, null);
@@ -95,14 +92,6 @@ public class MybatisXMLConfigBuilder extends BaseBuilder {
         this.parser = parser;
     }
 
-    /**
-     * TODO 重写改方法,返回值是 MybatisConfiguration 而不是 Configuration
-     */
-    @Override
-    public MybatisConfiguration getConfiguration() {
-        return (MybatisConfiguration) this.configuration;
-    }
-
     public Configuration parse() {
         if (parsed) {
             throw new BuilderException("Each XMLConfigBuilder can only be used once.");
@@ -114,7 +103,7 @@ public class MybatisXMLConfigBuilder extends BaseBuilder {
 
     private void parseConfiguration(XNode root) {
         try {
-            //issue #117 read properties first
+            // issue #117 read properties first
             propertiesElement(root.evalNode("properties"));
             Properties settings = settingsAsProperties(root.evalNode("settings"));
             loadCustomVfs(settings);
@@ -193,40 +182,40 @@ public class MybatisXMLConfigBuilder extends BaseBuilder {
         }
     }
 
-    private void pluginElement(XNode parent) {
+    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) createInstance(interceptor);
+                Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).getDeclaredConstructor().newInstance();
                 interceptorInstance.setProperties(properties);
                 configuration.addInterceptor(interceptorInstance);
             }
         }
     }
 
-    private void objectFactoryElement(XNode context) {
+    private void objectFactoryElement(XNode context) throws Exception {
         if (context != null) {
             String type = context.getStringAttribute("type");
             Properties properties = context.getChildrenAsProperties();
-            ObjectFactory factory = (ObjectFactory) createInstance(type);
+            ObjectFactory factory = (ObjectFactory) resolveClass(type).getDeclaredConstructor().newInstance();
             factory.setProperties(properties);
             configuration.setObjectFactory(factory);
         }
     }
 
-    private void objectWrapperFactoryElement(XNode context) {
+    private void objectWrapperFactoryElement(XNode context) throws Exception {
         if (context != null) {
             String type = context.getStringAttribute("type");
-            ObjectWrapperFactory factory = (ObjectWrapperFactory) createInstance(type);
+            ObjectWrapperFactory factory = (ObjectWrapperFactory) resolveClass(type).getDeclaredConstructor().newInstance();
             configuration.setObjectWrapperFactory(factory);
         }
     }
 
-    private void reflectorFactoryElement(XNode context) {
+    private void reflectorFactoryElement(XNode context) throws Exception {
         if (context != null) {
             String type = context.getStringAttribute("type");
-            ReflectorFactory factory = (ReflectorFactory) createInstance(type);
+            ReflectorFactory factory = (ReflectorFactory) resolveClass(type).getDeclaredConstructor().newInstance();
             configuration.setReflectorFactory(factory);
         }
     }
@@ -266,6 +255,7 @@ public class MybatisXMLConfigBuilder extends BaseBuilder {
         configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE")));
         configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null));
         configuration.setDefaultFetchSize(integerValueOf(props.getProperty("defaultFetchSize"), null));
+        configuration.setDefaultResultSetType(resolveResultSetType(props.getProperty("defaultResultSetType")));
         // TODO 统一 mapUnderscoreToCamelCase 属性默认值为 true
         configuration.setMapUnderscoreToCamelCase(booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), true));
         configuration.setSafeRowBoundsEnabled(booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false));
@@ -280,6 +270,7 @@ public class MybatisXMLConfigBuilder extends BaseBuilder {
         configuration.setReturnInstanceForEmptyRow(booleanValueOf(props.getProperty("returnInstanceForEmptyRow"), false));
         configuration.setLogPrefix(props.getProperty("logPrefix"));
         configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory")));
+        configuration.setShrinkWhitespacesInSql(booleanValueOf(props.getProperty("shrinkWhitespacesInSql"), false));
     }
 
     private void environmentsElement(XNode context) throws Exception {
@@ -311,7 +302,7 @@ public class MybatisXMLConfigBuilder extends BaseBuilder {
                 type = "DB_VENDOR";
             }
             Properties properties = context.getChildrenAsProperties();
-            databaseIdProvider = (DatabaseIdProvider) createInstance(type);
+            databaseIdProvider = (DatabaseIdProvider) resolveClass(type).getDeclaredConstructor().newInstance();
             databaseIdProvider.setProperties(properties);
         }
         Environment environment = configuration.getEnvironment();
@@ -321,22 +312,22 @@ public class MybatisXMLConfigBuilder extends BaseBuilder {
         }
     }
 
-    private TransactionFactory transactionManagerElement(XNode context) {
+    private TransactionFactory transactionManagerElement(XNode context) throws Exception {
         if (context != null) {
             String type = context.getStringAttribute("type");
             Properties props = context.getChildrenAsProperties();
-            TransactionFactory factory = (TransactionFactory) createInstance(type);
+            TransactionFactory factory = (TransactionFactory) resolveClass(type).getDeclaredConstructor().newInstance();
             factory.setProperties(props);
             return factory;
         }
         throw new BuilderException("Environment declaration requires a TransactionFactory.");
     }
 
-    private DataSourceFactory dataSourceElement(XNode context) {
+    private DataSourceFactory dataSourceElement(XNode context) throws Exception {
         if (context != null) {
             String type = context.getStringAttribute("type");
             Properties props = context.getChildrenAsProperties();
-            DataSourceFactory factory = (DataSourceFactory) createInstance(type);
+            DataSourceFactory factory = (DataSourceFactory) resolveClass(type).getDeclaredConstructor().newInstance();
             factory.setProperties(props);
             return factory;
         }
@@ -371,61 +362,31 @@ public class MybatisXMLConfigBuilder extends BaseBuilder {
     }
 
     private void mapperElement(XNode parent) throws Exception {
-        /*
-         * 定义集合 用来分类放置mybatis的Mapper与XML 按顺序依次遍历
-         */
         if (parent != null) {
-            //指定在classpath中的mapper文件
-            Set<String> resources = new HashSet<>();
-            //指向一个mapper接口
-            Set<Class<?>> mapperClasses = new HashSet<>();
-            setResource(parent, resources, mapperClasses);
-            // 依次遍历 首先 resource 然后 mapper
-            for (String resource : resources) {
-                ErrorContext.instance().resource(resource);
-                InputStream inputStream = Resources.getResourceAsStream(resource);
-                //TODO
-                XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource,
-                    configuration.getSqlFragments());
-                mapperParser.parse();
-            }
-            for (Class<?> mapper : mapperClasses) {
-                //TODO
-                configuration.addMapper(mapper);
-            }
-        }
-    }
-
-    /**
-     * 查找mybatis配置文件填充至Set集合
-     *
-     * @param parent    节点
-     * @param resources
-     * @param mapper
-     * @throws ClassNotFoundException
-     */
-    private void setResource(XNode parent, Set<String> resources, Set<Class<?>> mapper) throws ClassNotFoundException {
-        for (XNode child : parent.getChildren()) {
-            if ("package".equals(child.getName())) {
-                String mapperPackage = child.getStringAttribute("name");
-                ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<>();
-                resolverUtil.find(new ResolverUtil.IsA(Object.class), mapperPackage);
-                Set<Class<? extends Class<?>>> mapperSet = resolverUtil.getClasses();
-                mapper.addAll(mapperSet);
-            } 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) {
-                    resources.add(url);
-                } else if (resource == null && url == null && mapperClass != null) {
-                    Class<?> mapperInterface = Resources.classForName(mapperClass);
-                    mapper.add(mapperInterface);
+            for (XNode child : parent.getChildren()) {
+                if ("package".equals(child.getName())) {
+                    String mapperPackage = child.getStringAttribute("name");
+                    configuration.addMappers(mapperPackage);
                 } else {
-                    throw new BuilderException(
-                        "A mapper element may only specify a url, resource or class, but not more than one.");
+                    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);
+                        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 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.");
+                    }
                 }
             }
         }

+ 43 - 0
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/core/MybatisXMLConfigBuilderTest.java

@@ -0,0 +1,43 @@
+package com.baomidou.mybatisplus.core;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import lombok.Data;
+import org.apache.ibatis.session.Configuration;
+import org.junit.jupiter.api.Test;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author miemie
+ * @since 2020-06-15
+ */
+class MybatisXMLConfigBuilderTest {
+
+    @Test
+    void parse() throws IOException {
+        ResourceLoader loader = new DefaultResourceLoader();
+        Resource resource = loader.getResource("classpath:/MybatisXMLConfigBuilderTest.xml");
+        MybatisXMLConfigBuilder builder = new MybatisXMLConfigBuilder(resource.getInputStream(), null);
+        Configuration configuration = builder.parse();
+        assertThat(configuration).isInstanceOf(MybatisConfiguration.class);
+        assertThat(configuration.getMappedStatement("com.baomidou.mybatisplus.core.MybatisXMLConfigBuilderTest$EntityMapper.selectCount"))
+            .isNotNull();
+    }
+
+    interface EntityMapper extends BaseMapper<Entity> {
+
+    }
+
+    @Data
+    @TableName(autoResultMap = true)
+    static class Entity {
+        private Long id;
+        private String name;
+    }
+}

+ 9 - 0
mybatis-plus-core/src/test/resources/MybatisXMLConfigBuilderTest.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE configuration
+    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
+    "http://mybatis.org/dtd/mybatis-3-config.dtd">
+<configuration>
+    <mappers>
+        <mapper class="com.baomidou.mybatisplus.core.MybatisXMLConfigBuilderTest$EntityMapper"/>
+    </mappers>
+</configuration>

+ 1 - 1
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/spring/MybatisSqlSessionFactoryBean.java

@@ -442,7 +442,7 @@ public class MybatisSqlSessionFactoryBean implements FactoryBean<SqlSessionFacto
      */
     protected SqlSessionFactory buildSqlSessionFactory() throws Exception {
 
-        final MybatisConfiguration targetConfiguration;
+        final Configuration targetConfiguration;
 
         // TODO 使用 MybatisXmlConfigBuilder 而不是 XMLConfigBuilder
         MybatisXMLConfigBuilder xmlConfigBuilder = null;