首先感谢尚硅谷的老师讲解!
Mybatis流程分四步
:
1. 返回创建SqlSessionFactory对象 2. 返回SqlSession的实现类DefaultSqlSession对象 3. 返回一个MapperProxy的代理对象 4. 执行询流程。
第一步返回创建SqlSessionFactory对象
SqlSessionFactoryBuilder().build(inputStream);
如何得到配置文件的内容? 创建解析器解析全局配置文件
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
得到全局配置文件的配置内容 , 解析每一个标签把详细信息保存在Configuration
中
//解析配置文件标签 build(parser.parse()); propertiesElement(root.evalNode("properties")); Properties settings = settingsAsProperties(root.evalNode("settings")); loadCustomVfs(settings); typeAliasesElement(root.evalNode("typeAliases")); pluginElement(root.evalNode("plugins")); objectFactoryElement(root.evalNode("objectFactory"));
全局配置文件中有该属性可以解析mapper.xml文件 也保存到Configuration中
mappers> <package name="dao" /> </mappers>
Mapper.xml中的每个元素解析出来保存到全局配置中
将增删改查标签的每一个标签每一个属性也解析出来
封装到一个MapperedStatement
中
一个MapperedStatement就代表一个增删改查标签的详细信息
最后 return configuration;
包括全局配置信息和mapper.xml映射文件的各种信息
返回的configuration通过build
return new DefaultSqlSessionFactory(config);
configuration中
mapperRegistry属性保存的是代理类信息
mappedStatement属性保存的是增删查改等标签内容
总结:
配置文件的信息解析保存到Configureation对象中
返回包含Configureation的DefaultSqlSessionFactory
第二步 返回SqlSession的实现类DefaultSqlSession
对象
他里面包含了Executor(是用来增删改查的)和Configuration。
1. sqlSessionFactory.openSession();
2. 创建:获取一些信息 创建事务Transaction tx
3. configuration.newExecutor
根据Exector在全局配置中的类型,
创建出 BatchExecutor/ReuseExecutor/SimpleExecutor
4. 判断是否配置了二级缓存:
if (cacheEnabled)
5. 根据某列的值改变封装行为
进行封装
executor = new CachingExecutor(executor);
6. 调用拦截器方法,使用拦截器链
使用每一个拦截器重新包装Executor返回
executor = (Executor) interceptorChain.pluginAll(executor);
最后:
new DefaultSqlSession(configuration, executor, autoCommit);
总结:
创建DefaultSqlSession返回,包含Configurarion和Executor
第三步 getMapper使用MapperProxyFactory创建一个MapperProxy的代理对象
代理对象里面包含了 DefaultSqlSession(Executor)
动态代理对象就可以使用DefaultSqlSession中的Executor
实现增删改查
configuration.getMapper
mapperRegistry.getMapper中:
根据接口类型knownMappers.get(type)
获得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<T>(sqlSession, mapperInterface, methodCache); return newInstance(mapperProxy); }
过程:创建MapperProxy,它是一个InvocationHandler
然后创建MapperProxy的代理对象
MapperProxy<T> implements InvocationHandler, Serializable { //里面有接口信息 private final SqlSession sqlSession; private final Class<T> mapperInterface; private final Map<Method, MapperMethod> methodCache;
第四步:一张图明白查询流程
Mybatis总结:
1.根据配置文件(全局和sql映射配置)初始化configuration对象
2.创建一个DefaultSqlSession对象,它里面包含Configuration以及Executor(根据全局配置文件属性defaultExecutorType值,创建出对应Executor)
3.DefaultSqlSession.getMapper():拿到Mapper接口对应的MapperProxy,
4.MapperProxy里面有DefaultSqlSession(当然了DefaultSqlSession里面有Executor)
5.执行正删改查方法:
(1) (直接用的是代理对象,代理对象调用DefaultSqlSession[Exector]进行增删改查),Exector会创建
(2) 一个Statement对象(同时也创建了StatementHandler,ParameterHandler,ResultSetHandler),
(3) 调用StatementHandler的预编译参数以及设置参数值(ParameterHandler给Sql语句设置参数值)
(4) 调用StatementHandler的增删改查方法
(5) ResultSetHandler封装结果值
用图说明一下流程:
注意,四大对象每个创建的时候,都有一个拦截器链interceptorChain.pluginAll(parameterHandler),理解这个对些Mybatis的插件很有帮助.
这里主要涉及到了插件,后面会介绍。这里简单知道 pluginAll是用来拦截四大对象,
相当于web的拦截器作用
转: https://blog.csdn.net/qq_38409944/article/details/82494187