• Mybatis 系列6-结合源码解析节点配置:objectFactory、databaseIdProvider、plugins、mappers


    【Mybatis 系列10-结合源码解析mybatis 执行流程】

    【Mybatis 系列9-强大的动态sql 语句】

    【Mybatis 系列8-结合源码解析select、resultMap的用法】 

    【Mybatis 系列7-结合源码解析核心CRUD配置及用法】

    【Mybatis 系列6-结合源码解析节点配置objectFactory、databaseIdProvider、plugins、mappers】

    【Mybatis 系列5-结合源码解析TypeHandler】 

    【Mybatis 系列4-结合源码解析节点typeAliases】

    【Mybatis 系列3-结合源码解析properties节点和environments节点】

    【Mybatis 系列2-配置文件】

    【Mybatis 系列1-环境搭建】

    上篇系列5中 简单看了一下TypeHandler, 本次将结束对于mybatis的配置文件的学习,

    本次涉及到剩下没提及到的几个节点的配置:objectFactory、databaseIdProvider、plugins、mappers。

    简单介绍一下这几个配置的作用:

    1、objectFactory是干什么的? 需要配置吗?

    MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。默认情况下,我们不需要配置,mybatis会调用默认实现的objectFactory。 除非我们要自定义ObjectFactory的实现, 那么我们才需要去手动配置。

    那么怎么自定义实现ObjectFactory? 怎么配置呢?

     

    自定义ObjectFactory只需要去继承DefaultObjectFactory(是ObjectFactory接口的实现类),并重写其方法即可。不多说,后面再具体讲解。

    写好了ObjectFactory, 仅需做如下配置:

    1 <configuration>
    2     ......
    3     <objectFactory type="org.mybatis.example.ExampleObjectFactory">
    4         <property name="someProperty" value="100"/>
    5     </objectFactory>
    6     ......
    7   </configuration>

     

    2、plugin有何作用? 需要配置吗?

     

    plugins 是一个可选配置。mybatis中的plugin其实就是个interceptor, 它可以拦截Executor 、ParameterHandler 、ResultSetHandler 、StatementHandler 的部分方法,处理我们自己的逻辑。

    Executor就是真正执行sql语句的东西, ParameterHandler 是处理我们传入参数的,还记得前面讲TypeHandler的时候提到过,mybatis默认帮我们实现了不少的typeHandler, 当我们不显示配置typeHandler的时候,mybatis会根据参数类型自动选择合适的typeHandler执行,其实就是ParameterHandler 在选择。ResultSetHandler 就是处理返回结果的。

     

    怎么自定义plugin ? 怎么配置?

    要自定义一个plugin, 需要去实现Interceptor接口, 这儿不细说, 后面实战部分会详细讲解。定义好之后,配置如下:

    1 <configuration>
    2     ......
    3     <plugins>
    4       <plugin interceptor="org.mybatis.example.ExamplePlugin">
    5         <property name="someProperty" value="100"/>
    6       </plugin>
    7     </plugins>
    8     ......
    9   </configuration>

     

    3、mappers, 这下引出mybatis的核心之一了,mappers作用 ? 需要配置吗?

     

    mappers 节点下,配置我们的mapper映射文件, 所谓的mapper映射文件,就是让mybatis 用来建立数据表和javabean映射的一个桥梁。在我们实际开发中,通常一个mapper文件对应一个dao接口, 这个mapper可以看做是dao的实现。所以,mappers必须配置

    那么怎么配置呢?

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

    本篇仅作简单介绍, 更高级的使用以及其实现原理,会在后面的实战部分进行详细讲解。 这几个节点的解析源码,与之前提到的那些节点的解析类似,故此处不再讲。 我将源码折叠, 需要的可以打开看看。

     1 **
     2  * objectFactory 节点解析
     3  */
     4 private void objectFactoryElement(XNode context) throws Exception {
     5     if (context != null) {
     6       //读取type属性的值, 接下来进行实例化ObjectFactory, 并set进 configuration
     7       //到此,简单讲一下configuration这个对象,其实它里面主要保存的都是mybatis的配置
     8       String type = context.getStringAttribute("type");
     9       //读取propertie的值, 根据需要可以配置, mybatis默认实现的objectFactory没有使用properties
    10       Properties properties = context.getChildrenAsProperties();
    11       
    12       ObjectFactory factory = (ObjectFactory) resolveClass(type).newInstance();
    13       factory.setProperties(properties);
    14       configuration.setObjectFactory(factory);
    15     }
    16  }
    17  
    18   
    19   /**
    20    * plugins 节点解析
    21    */
    22   private void pluginElement(XNode parent) throws Exception {
    23     if (parent != null) {
    24       for (XNode child : parent.getChildren()) {
    25         String interceptor = child.getStringAttribute("interceptor");
    26         Properties properties = child.getChildrenAsProperties();
    27         //由此可见,我们在定义一个interceptor的时候,需要去实现Interceptor, 这儿先不具体讲,以后会详细讲解
    28         Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).newInstance();
    29         interceptorInstance.setProperties(properties);
    30         configuration.addInterceptor(interceptorInstance);
    31       }
    32     }
    33   }
    34   
    35   /**
    36    * mappers 节点解析
    37    * 这是mybatis的核心之一,这儿先简单介绍,在接下来的文章会对它进行分析
    38    */
    39   private void mapperElement(XNode parent) throws Exception {
    40     if (parent != null) {
    41       for (XNode child : parent.getChildren()) {
    42         if ("package".equals(child.getName())) {
    43           //如果mappers节点的子节点是package, 那么就扫描package下的文件, 注入进configuration
    44           String mapperPackage = child.getStringAttribute("name");
    45           configuration.addMappers(mapperPackage);
    46         } else {
    47           String resource = child.getStringAttribute("resource");
    48           String url = child.getStringAttribute("url");
    49           String mapperClass = child.getStringAttribute("class");
    50           //resource, url, class 三选一
    51           
    52           if (resource != null && url == null && mapperClass == null) {
    53             ErrorContext.instance().resource(resource);
    54             InputStream inputStream = Resources.getResourceAsStream(resource);
    55             //mapper映射文件都是通过XMLMapperBuilder解析
    56             XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
    57             mapperParser.parse();
    58           } else if (resource == null && url != null && mapperClass == null) {
    59             ErrorContext.instance().resource(url);
    60             InputStream inputStream = Resources.getUrlAsStream(url);
    61             XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
    62             mapperParser.parse();
    63           } else if (resource == null && url == null && mapperClass != null) {
    64             Class<?> mapperInterface = Resources.classForName(mapperClass);
    65             configuration.addMapper(mapperInterface);
    66           } else {
    67             throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
    68           }
    69         }
    70       }
    71     }
    72   }

    从下篇文章开始,将会开始接触到mybatis的核心部分。

    by:一只阿木木

  • 相关阅读:
    Angular
    linux mysql 5.7.25 安裝
    J2CACHE 两级缓存框架
    MYSQL 事务测试
    安装配置ftp服务器
    使用docker 安装 GITLIB
    Elastic serarch 安装
    centos firewalld 基本操作【转】
    KAFKA 监控管理界面 KAFKA EAGLE 安装
    redis 的一主二从三哨兵模式
  • 原文地址:https://www.cnblogs.com/yizhiamumu/p/8996920.html
Copyright © 2020-2023  润新知