mybatis(六)objectFactory、plugins、mappers簡介與配置

上篇文章簡單看了一下TypeHandler, 本次將結束對於mybatis的配置文件的學習, 本次涉及到剩下沒說起到的幾個節點的配置:objectFactory、databaseIdProvider、plugins、mappers。 java

那麼,接下來,就簡單介紹一下這幾個配置的做用吧: sql

一、objectFactory是幹什麼的? 須要配置嗎? mybatis

  MyBatis 每次建立結果對象的新實例時,它都會使用一個對象工廠(ObjectFactory)實例來完成。默認的對象工廠須要作的僅僅是實例化目標類,要麼經過默認構造方法,要麼在參數映射存在的時候經過參數構造方法來實例化。默認狀況下,咱們不須要配置,mybatis會調用默認實現的objectFactory。 除非咱們要自定義ObjectFactory的實現, 那麼咱們才須要去手動配置。 app

  那麼怎麼自定義實現ObjectFactory? 怎麼配置呢? ide

  自定義ObjectFactory只須要去繼承DefaultObjectFactory(是ObjectFactory接口的實現類),並重寫其方法便可。具體的,本處很少說,後面再具體講解。 學習

  寫好了ObjectFactory, 僅需作以下配置:  ui

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



二、plugin有何做用? 須要配置嗎? url

  plugins 是一個可選配置。mybatis中的plugin其實就是個interceptor, 它能夠攔截Executor 、ParameterHandler 、ResultSetHandler 、StatementHandler 的部分方法,處理咱們本身的邏輯。Executor就是真正執行sql語句的東西, ParameterHandler 是處理咱們傳入參數的,還記得前面講TypeHandler的時候提到過,mybatis默認幫咱們實現了很多的typeHandler, 當咱們不顯示配置typeHandler的時候,mybatis會根據參數類型自動選擇合適的typeHandler執行,其實就是ParameterHandler 在選擇。ResultSetHandler 就是處理返回結果的。 spa

  怎麼自定義plugin ? 怎麼配置? code

  要自定義一個plugin, 須要去實現Interceptor接口, 這兒不細說, 後面實戰部分會詳細講解。定義好以後,配置以下:

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



三、mappers, 這下引出mybatis的核心之一了,mappers做用 ? 須要配置嗎?

  mappers 節點下,配置咱們的mapper映射文件, 所謂的mapper映射文件,就是讓mybatis 用來創建數據表和javabean映射的一個橋樑。在咱們實際開發中,一般一個mapper文件對應一個dao接口, 這個mapper能夠看作是dao的實現。因此,mappers必須配置

  那麼怎麼配置呢?

<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>



本篇僅做簡單介紹, 更高級的使用以及其實現原理,會在後面的實戰部分進行詳細講解。

這幾個節點的解析源碼,與以前提到的那些節點的解析相似,故此處再也不講。

/**
 * 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文件的配置及使用, 並經過源碼進一步深刻核心。

相關文章
相關標籤/搜索