【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, 仅需做如下配置:

 <configuration>
......
<objectFactory type="org.mybatis.example.ExampleObjectFactory">
<property name="someProperty" value="100"/>
</objectFactory>
......
</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接口, 这儿不细说, 后面实战部分会详细讲解。定义好之后,配置如下:

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

3、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的核心部分。

by:一只阿木木

Mybatis 系列6-结合源码解析节点配置:objectFactory、databaseIdProvider、plugins、mappers的更多相关文章

  1. Mybatis 系列4-结合源码解析节点:typeAliases

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

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

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

  3. Mybatis 系列10-结合源码解析mybatis 的执行流程

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

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

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

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

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

  6. Mybatis 系列5-结合源码解析TypeHandler

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

  7. 死磕 java同步系列之Phaser源码解析

    问题 (1)Phaser是什么? (2)Phaser具有哪些特性? (3)Phaser相对于CyclicBarrier和CountDownLatch的优势? 简介 Phaser,翻译为阶段,它适用于这 ...

  8. 死磕 java同步系列之StampedLock源码解析

    问题 (1)StampedLock是什么? (2)StampedLock具有什么特性? (3)StampedLock是否支持可重入? (4)StampedLock与ReentrantReadWrite ...

  9. 死磕 java同步系列之ReentrantReadWriteLock源码解析

    问题 (1)读写锁是什么? (2)读写锁具有哪些特性? (3)ReentrantReadWriteLock是怎么实现读写锁的? (4)如何使用ReentrantReadWriteLock实现高效安全的 ...

随机推荐

  1. vue中在页面渲染完之后获取元素(否则动态渲染的元素获取不到)

    两种方法: 方法一: 使用$nextTick,在异步获得数据之后再获取元素: 方法二: 在then之后再获取该元素: 问题2:vue中监听改变数组的方法: let idx =; this.listIn ...

  2. 07机器学习实战k-means

    K-Means原理初探 K-Means算法的思想很简单,对于给定的样本集,按照样本之间的距离大小,将样本集划分为K个簇.让簇内的点尽量紧密的连在一起,而让簇间的距离尽量的大. 如果我们想直接求上式的最 ...

  3. SecureCRT突然卡死的问题

    SecureCRT作为著名的SSHclient,经经常使用于登陆远程server. 在上面编辑文本,特别是用vi打开两个文本,而且须要切换时.非常easy出现卡死的现象,不能接受不论什么的键盘输入. ...

  4. 线性代数及其应用 (David C.Lay, Steven R.Lay 著)

    第1章 线性代数中的线性方程组 (已看) 介绍性实例 经济学与工程中的线性模型 1.1 线性方程组 1.2 行化简与阶梯形矩阵 1.3 向量方程 1.4 矩阵方程Ax=b 1.5 线性方程组的解集 1 ...

  5. WikiBooks/Cg Programming

    https://en.wikibooks.org/wiki/Cg_Programming Basics Minimal Shader(about shaders, materials, and gam ...

  6. Tanks!Tutorial 学习

    using UnityEngine; namespace Complete { public class CameraControl : MonoBehaviour { /// <summary ...

  7. Laya播放unity特效

    杭州-fun 2017/12/5 20:47:12  其实网上就有你搜下就有了现成的脚本,设置帧数和截取时间它会截屏并保存成贴图导入laya生成atlas就能用了   就是unity的截屏功能   就 ...

  8. 上外网tunnel手段

    需要的软件 1, httptunnel软件,包括服务端和客户端,家里开启服务端,公司开启客户端 2,(可选)proxifier PE,用来在公司check 代理工作是否正常 3,动态域名服务,在家里用 ...

  9. 深入理解 content 计数器

    计数器可以说是content的重点, 因为此功能非常强大, 实用, 并且不具有可替代性, 甚至可以实现连JavaScript都不好实现的效果. 所谓css计数器效果, 就是使用CSS代码实现随元素的数 ...

  10. Linux下vim基本操作和清空文件内容的常用方法

    以前都是用的很土的办法,大概有以下几种.1.直接删除,创建一个新的同名文件(这种方法的弊端是有可能这个文件带着权限或者是属性,那么你新建这个文件后有可能会导致权限不正确或者丢失属性).2.使用vim编 ...