运行步骤:
1、获取SqlSessionFactory对象
2、获取SqlSession对象
3、获取接口的代理对象(MapperProxy)
4、执行增删改查方法
Mybatis在四大对象的创建过程中,都会有插件进行介入。插件可以利用动态代理机制一层层的包装目标对象,从而实现在目标对象执行目标方法之前进行拦截的效果。
Mybatis允许在已映射语句执行过程中的某一点进行拦截调用
默认情况下,Mybatis允许使用插件来拦截的方法调用包括:
- Executor(update,query,flushStatements,commit,rollback,getTransaction,close,isClosed)
- ParameterHandler(getParameterObject,setParameters)
- ResultSetHandler(handleResultSets,handleOutputParameters)
- StatementHandler(prepare,parameterize,batch,update,query)
1、获取SqlSessionFactory对象
所以在sql映射文件中对应的增删改查标签中的内容,实际上在创建SqlSessionFactory的时候就已经将其转换成为MappedStatement对象。如下是MappedStatement对象生成的具体数据:
最终所有的配置信息都保存在configuration中,configuration中两个非常重要的属性mappedStatements和mappedRegistry,mappedStatements存放的是所有的封装sql映射文件中的增删改查的mappedStatement,mappedRegistry中有一个Hashmap属性knownMappers属性,保存了Mapper以及其对应的MapperProxyFactory,包括全局配置信息以及sql映射文件信息,如下;
总结:把配置文件的信息解析并保存在Configuration对象中,返回包含Configuration的DefaultSqlSessionFactory对象。
2、获取SqlSession对象
上面在全局配置文件中通过DefaultExecutorType设置ExecutorType,默认是SIMPLE,上面图中写错了。最终返回的是DefaultSqlSession,返回的DefaultSqlSession包含了创建的Executor和Configuration。
3、获取接口的代理对象(MapperProxy)
DefaultSqlSession
@Override
public <T> T getMapper(Class<T> type) {
return configuration.<T>getMapper(type, this);
}
Configuration
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return mapperRegistry.getMapper(type, sqlSession);
}
MapperRegistry
@SuppressWarnings("unchecked")
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
}
try {
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}
MapperProxyFactory
@SuppressWarnings("unchecked")
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
4、执行增删改查方法
整个流程总结:
1、根据配置文件(全局,sql映射文件)初始化Configuration对象
2、创建一个DefaultSqlSession对象
里面包含Configuration对象和Executor(根据全局配置文件中的defaultExecutorType创建对应Executor对象)
3、DefaultSqlSession.getMapper(),拿到Mapper接口对应的MapperProxy
4、MapperProxy里面有DefaultSqlSession
5、执行增删改查方法:
- 调用DefaultSqlSession的增删改查(Executor)
- 创建一个StatementHandler对象(同时也会创建ParameterHandler和ResultSetHandler对象)
- 调用StatementHandler预编译参数以及设置参数值(ParameterHandler来给sql设置参数)
- 调用StatementHandler的增删改查方法
- ResultSetHandler封装结果
注意:四大对象,Executor,ParameterHandler,ResultSetHandler,StatementHandler在创建的时候都会调用一个interceptorChain.pluginAll(四大对象)