Home  >  Article  >  Java  >  An in-depth explanation of the Mybatis series (6)---Introduction and configuration of objectFactory, plugins, and mappers

An in-depth explanation of the Mybatis series (6)---Introduction and configuration of objectFactory, plugins, and mappers

黄舟
黄舟Original
2017-03-02 10:50:151478browse

The previous article "In-depth introduction to Mybatis series (5)---Introduction and configuration of TypeHandler (mybatis source code)" took a brief look at TypeHandler. This time we will end the study of the configuration file of mybatis. This time it involves the configuration of the remaining nodes that are not mentioned: objectFactory, databaseIdProvider, plugins, and mappers.

So, next, let’s briefly introduce the functions of these configurations:

1. What does objectFactory do? Need to configure?

 Every time MyBatis creates a new instance of the result object, it will use an object factory (ObjectFactory) instance to complete it. All the default object factory needs to do is instantiate the target class, either through the default constructor or through the parameter constructor if a parameter map exists. By default, we do not need to configure, mybatis will call the default implemented objectFactory. Unless we want to customize the implementation of ObjectFactory, then we need to configure it manually.

So how to customize the implementation of ObjectFactory? How to configure it?

To customize ObjectFactory, you only need to inherit DefaultObjectFactory (which is the implementation class of ObjectFactory interface) and rewrite its methods. I won’t go into detail here and will explain it in detail later.

After writing the ObjectFactory, you only need to configure it as follows:


<configuration>
    ......    <objectFactory type="org.mybatis.example.ExampleObjectFactory">
        <property name="someProperty" value="100"/>
    </objectFactory>
    ......  </configuration


2. What is the role of the plugin? Need to configure?

 Plugins are an optional configuration. The plugin in mybatis is actually an interceptor. It can intercept some methods of Executor, ParameterHandler, ResultSetHandler, and StatementHandler to process our own logic. Executor is what actually executes sql statements. ParameterHandler is what processes the parameters we pass in. I still remember what I mentioned when talking about TypeHandler earlier. Mybatis helps us implement a lot of typeHandlers by default. When we do not explicitly configure typeHandler, mybatis The appropriate typeHandler will be automatically selected for execution based on the parameter type, which is actually ParameterHandler. In choosing. ResultSetHandler handles the returned results.

How to customize the plugin? How to configure it?

To customize a plugin, you need to implement the Interceptor interface. I won’t go into details here, but will be explained in detail in the practical part later. After defining it, the configuration is as follows:

<configuration>
    ......    <plugins>
      <plugin interceptor="org.mybatis.example.ExamplePlugin">
        <property name="someProperty" value="100"/>
      </plugin>
    </plugins>
    ......  </configuration>

3. Mappers, this leads to one of the cores of mybatis. What is the role of mappers? Do I need to configure it?

Under the mappers node, configure our mapper mapping file. The so-called mapper mapping file is a bridge used by mybatis to establish mapping between data tables and javabeans. In our actual development, usually a mapper file corresponds to a dao interface, and this mapper can be regarded as the implementation of dao. Therefore, mappers must be configured.

So how to configure it?

<configuration>
    ......    <mappers>
      <!-- 第一种方式:通过resource指定 -->
    <mapper resource="com/dy/dao/userDao.xml"/>
    
     <!-- 第二种方式, 通过class指定接口,进而将接口与对应的xml文件形成映射关系
             不过,使用这种方式必须保证 接口与mapper文件同名(不区分大小写), 
             我这儿接口是UserDao,那么意味着mapper文件为UserDao.xml 
     <mapper class="com.dy.dao.UserDao"/>      -->
      
      <!-- 第三种方式,直接指定包,自动扫描,与方法二同理 
      <package name="com.dy.dao"/>      -->
      <!-- 第四种方式:通过url指定mapper文件位置
      <mapper url="file://........"/>       -->
  </mappers>
    ......  </configuration>

This article is only a brief introduction. More advanced usage and its implementation principles will be explained in detail in the practical part later.

The parsing source code of these nodes is similar to the parsing of those nodes mentioned before, so it will not be discussed here. I folded the source code, you can open it if needed.

/**
 * objectFactory 节点解析 
 */private void objectFactoryElement(XNode context) throws Exception {    
 if (context != null) {      
 //读取type属性的值, 接下来进行实例化ObjectFactory, 并set进 configuration      
 //到此,简单讲一下configuration这个对象,其实它里面主要保存的都是mybatis的配置
      String type = context.getStringAttribute("type");      
      //读取propertie的值, 根据需要可以配置, mybatis默认实现的objectFactory没有使用properties
      Properties properties = context.getChildrenAsProperties();
      
      ObjectFactory factory = (ObjectFactory) resolveClass(type).newInstance();
      factory.setProperties(properties);
      configuration.setObjectFactory(factory);
    }
 } 
  
  /**
   * plugins 节点解析   */
  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的时候,需要去实现Interceptor, 这儿先不具体讲,以后会详细讲解
        Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).newInstance();
        interceptorInstance.setProperties(properties);
        configuration.addInterceptor(interceptorInstance);
      }
    }
  }  
  /**
   * mappers 节点解析
   * 这是mybatis的核心之一,这儿先简单介绍,在接下来的文章会对它进行分析   */
  private void mapperElement(XNode parent) throws Exception {    if (parent != null) {      for (XNode child : parent.getChildren()) {        if ("package".equals(child.getName())) {          //如果mappers节点的子节点是package, 那么就扫描package下的文件, 注入进configuration
          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, url, class 三选一
          
          if (resource != null && url == null && mapperClass == null) {
            ErrorContext.instance().resource(resource);
            InputStream inputStream = Resources.getResourceAsStream(resource);            //mapper映射文件都是通过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 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.");
          }
        }
      }
    }
  }

本次就简单的到此结束, 从下篇文章开始,将会开始接触到mybatis的核心部分,不过首先还是要讲mapper文件的配置及使用, 并通过源码进一步深入核心。

 以上就是深入浅出Mybatis系列(六)---objectFactory、plugins、mappers简介与配置的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn