Mybatis源码分析

Mybatis源码解读

源码关键词

阅读源码中一些关键字,有利于快速理解类的意思:

Resolver:解析器

此接口表示用于名称解析的“中间上下文”。
Resolver接口包含由上下文实现的方法,这些方法不支持Context的子类型,但是可以充当中间上下文以实现解析目的。

传递给任何方法的Name参数归调用者所有。 服务提供者将不会修改该对象或保留对其的引用。 调用者拥有任何方法返回的ResolveResult对象。 调用者可以随后对其进行修改; 服务提供商可能不会。

Handler:控制器

常被用作线程间传递消息的组件,而且还可以用于跨进程

Parser解析器

parser,一般是指把某种格式的文本(字符串)转换成某种数据结构的过程。最常见的 parser,是把程序文本转换成编译器内部的一种叫做“抽象语法树”(AST)的数据结构。也有简单一些的 parser,用于处理 CSV,JSON,XML 之类的格式。

Statement声明

用于执行静态SQL语句并返回其产生的结果的对象。

statements就像一个车,,当从数据库中取数据的时候首先要建立一个connection,这个东西是java程序和数据库的一个连接,可以把connection想成一条路,然后你怎么把东西拉回来,就要用到这个statements,把东西拉回来之后,再组装起来,放到一个resultSet中

Mybatis结构图

获取SqlSessionFactory对象

1.通过parseConfiguration()在configuration标签中设置 properties、settings、environments等属性标签
将所有的配置信息放在了Configuration对象中

2.XMLConfigBuilder会调用XPathParser解析所有的Xml文件,然后调用XMLMapperEntityResolver来解析实体类接口的XXXMapper.xml文件(分析其中的增删改查标签),解析是SAX解析.

<select id=""resultType="等属性是通过parseStatementNode()解析的>
会将XxxMapper.xml中的<select>等标签解析成 MappedStatement对象
即MappedStatement对 就是<select>等标签

3.MappedStatement、environment等信息都存在于Configuration中,基本所有的配置信息、增删改标签全部存在于Configuration中

4.最后将将这个config(Configuration对象)传递给DefaultSqlSessionFactory(SqlSessionFactory接口的实现类),通过返回一个DefaultSqlSessionFactory的对象,然后SqlSessionFactory对象通过build方法产生一个SqlSessionFactory对象

时序图:

获取SqlSession对象

1.sessionFactory.openSession()之后,会去调用DefaultSqlSessionFactory去加载配置,主要是一些默认的配置,例如DefaultExecutorType(默认的值是SIMPLE),还会去调用Environment来加载一些事物配置以及数据配置,然后返回一个执行器(Executor),然后将configuration, executor传递给DefaultSqlSession,创造一个SqlSession对象返回.

2.configuration.newExecutor(tx, execType) ========>SimpleExecutor
根据不同的类型execType,产生不同的Executor,并且会对执行器进行拦截操作

3.executor = (Executor) interceptorChain.pluginAll(executor);

通过装饰模式,将刚产生的executor 包装成一个更加强大的 executor。
作用:如果要给MyBatis写自己的插件,就可以通过拦截器实现。
插件开发:

1、写插件

2、放入拦截器

返回DefaultSqlSession(configuration,executor,事务),最终得到SqlSession对象

SqlSession===> openSession() =>openSessionFromDataSource()=>DefaultSqlSession对象

SqlSession===> DefaultSqlSession对象 ===>执行SQL

FileInputSTream("d://abc.txt")===>InputSTream,字符串->变成对象

时序图:

获取XxxMapper对象

执行增删改查=>MapperProxy/invoke()=>InvocationHandler :JDK动态代理接口

过程用到了动态代理模式:

增删改查 =>代理对象 (MapperProxy对象)=>代理对象 帮我们“代理执行” 增删改查

XxxMapper代理对象: MapperProxy对象

mapperMethod.execute(sqlSession,args) :实际调用增删改查的方法 ,依靠了sqlSession中的configuration和 executor..

处理增删改查方法的参数:method.convertArgsToSqlCommandParam(args);: 如果參數是0个,reutrun null ;如果参数是1,返回第一个 ; 如果有多个参数 放入map中

查询方法:selectOne() ===>selectList() : configuration.getMappedStatement() 即获取到用于增删改查的对象

boundSql :将我们写的SQL 和 参数值进行了拼接后的对象,即最终能被真正执行的SQL

执行SQL 是通过Executor
如果缓存中没有要查询的内容,则进入数据库 真实查询:queryFromDatabase()

mybatis使用的jdbc對象是PreparedStatement
底层执行增删改查:PreparedStatement的execute()

MyBatis底层在执行CRUD时 可能会涉及到四个处理器:StatementHandler ParameterHandler TypeHandler ResultSetHandler

XxxMapper:
SqlSession(configuration,executor,事务)、代理接口的对象(MapperInterface)、methodCache(存放查询缓存, 底层是CurrentHashMap)

(代理接口中的方法、mapper.xml中的<select>等标签)

MapperProxy构建时序图:

Executor执行流程

posted @ 2020-12-09 23:13  等不到的口琴  阅读(139)  评论(0编辑  收藏  举报