目录
一.Mybatis核心对象
Configuration:存放所有配置信息的类,包括properties配置、plugin插件、Mapper映射、数据源等。
SqlSessionFactory:简而言之就是创建SqlSession的工厂类,通常由SqlSessionFactoryBuilder根据Configuration配置类生成。
SqlSession:SqlSession是一个接口,定义了增、删、改、查、事务回滚提交等接口。SqlSession中的sql操作是通过Executor、StatementHandler、ParameterHandler和ResultHandler来完成数据库的操作和数据返回的。
Executor代表执行器,调度StatementHandler、ParameterHandler和ResultHandler等来执行SQL。
StatementHandler的角色和JDBC中的PreparedStatement是类似的,通过调用PreparedStatement完成操作,是SQLSession中核心的对象承上启下。
ParameterHandler比较好理解,用来处理参数映射、转换。
ResultHandler是专门处理数据结果集的,把一行行的数据库记录映射成Java对象。
二.SelSession四大对象
mybatis中的插件可以简单的理解成在四大对象调用前后织入自定义代码,如需要修改SQL通常拦截StatementHandler对象,相比于其他三大对象,StatementHandler通常是最常拦截的一个对象。
三.Mybatis 插件原理
mybatis插件技术使用了动态代理和责任链模式,动态代理实现在四大对象调用前后执行自定义代码,责任链模式把多个拦截器合成一条调用链,解耦请求调用者和处理者集合,便于扩展自定义插件。
3.1 mybatis插件接口
mybatis定义了插件接口Interceptor,Interceptor接口有三个方法intercept、plugin、setProperties。
intercept方法是核心方法,自定义逻辑通常定义在这个方法内。
plugin方法是用于生成代理对于,jdk8以上版本可以不适用Interceptor接口自带的静态方法。
setProperties方法在插件初始化时设置xml配置文件中定义的属性。
除此之外还需要在类中声明插件拦截的方法,我们在下文中介绍。
3.2 插件初始化
XMLConfigBuilder从xml配置文件解析插件配置
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) resolveClass(interceptor).newInstance();
interceptorInstance.setProperties(properties);
configuration.addInterceptor(interceptorInstance);
}
}
}
3.3 动态代理四大对象
Configuration对象调用newExecutor生成调度器,最终调用拦截器链的pluginAll方法层层生成代理对象。
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
executor = new SimpleExecutor(this, transaction);
}
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
ParameterHandler parameterHandler &