mybatis源码分析全体流程图
2025-01-22 14:22:00 0 举报
MyBatis是一款支持定制化SQL、存储过程以及高级映射的持久层框架。核心流程开始于SqlSessionFactoryBuilder解析配置文件或配置对象,构建SqlSessionFactory,该工厂负责生产SqlSession实例。SqlSession是一个线程私有的会话,用于发起对数据库的操作。 在SqlSession中,用户操作与数据库之间通过Executor进行中间管理,Executor负责管理StatementHandler、ParameterHandler、ResultSetHandler等组件。StatementHandler负责管理JDBC Statement,ParameterHandler负责处理SQL语句的参数,ResultSetHandler用于处理结果集。 整个流程中,最重要的环节之一是SQL解析,MyBatis通过XML或注解方式接收用户定义的SQL语句,并将其转化为一个MappedStatement对象。该对象将SQL语句、输入参数映射等封装起来,为后续的SQL执行提供了详细信息。 整个流程涉及大量的反射和代理技术,如SqlSession的增删改查方法多数是通过代理实现的,而ResultMap的处理则是利用Java反射技术动态处理数据和对象的映射关系,确保操作的灵活与高效。通过这些核心组件与流程的协作,MyBatis实现了与JDBC API相比,更加简化和高效的数据库操作体验。
作者其他创作
大纲/内容
把MappedStatement对象添加到mappedStatements集合中保存
组装mapper.xml文件路径,加载mapper.xml文件。inputStream = Resources.getResourceAsStream(resource)
否
delegate.query()通过CachingExecutor里面的SimpleExecutor执行器类具体的sql语句
configurationElement解析mapper节点
BatchExecutor批量执行器(批量更新)
遍历resultMaps集合按照规则规则对ResultSet进行映射
解析reflectorFactory属性
调用XMLStatementBuilder对象的parseStatementNode方法对sql进行解析
判断执行的方法是否是继承自Object.class类
将包下所有类加入到knownMappers集合中
判断mappers子节点名称是否是package
getMappedStatement通过此方法获取对应MappedStatementd对象,该对象中包含了具体SQL语句相关信息
通过之前创建好的执行器CachingExecutor类执行具体的sql语句
判断该接口是否已经加载过
判断方法的返回值是否游标returnsCursor
查询二级缓存是否有结果集
扫描指定的包,获取该包路径下所有的所有的接口,遍历所有的接口,对对应的mapper.xml文档一一进行解析
返回值是否是map
inputStream = Resources.getResourceAsStream(resource)
3.做好解析前的准备工作
创建SqlSessionFactoryBuilder对象来解析xml配置文件
configuration.newStatementHandler()获取sql语句处理器RoutingStatementHandler对象
将args数组转换成SQL语句对应的参数列表
解析environments属性
如果是insert语句
command.getType()判断SQL语句的类型
返回空
构建sqlSession对象
是
SimpleExecutor简单执行器
直接返回结果集
判断方法的返回值是否是集合或者数组returnsMany
如果是Select语句
创建ParamNameResolver对象用于对方法参数的名称进行处理即@param注解
获取mappers标签的属性值
1.创建执行器Executor对象时,需要传入dataSource数据源对象,所以这里需要获取DataSource对象,但是没有创建连接2.默认执行器Executor对象是SIMPLE
CALLABLE
解析properties属性
判断方法是否有返回值returnsVoid
判断该类是不是接口
1.创建Xpath对象2.创建Dcument对象
getFirstResultSet(stmt)获取第一个结果集
创建jdk8版本DefaultMethodInvoker对象或者创建jdk9版本DefaultMethodInvoker对象
解析settings属性
将查询到的结果集结果添加到一级缓存localCache中
是否有嵌套结果集
通过jdk代理的方式创建mapper接口的代理对象
设置Executor对象
executeForMany()结果有多条记录
3.通过MapperBuilderAssistant创建MappedStatement对象
使用sqlSessionFactory的openSession方法来构建sqlSession对象
handleResultSet此方法用于进行具体的结果映射
以构造方式赋值
通过sqlSession对象来获取具体操作Mapper的对象
初始化rowBoundsIndex、resultHandlerIndex字段
1.解析sql语句节点相关属性
设置 mapper接口对应的Class对象mapperInterface
设置缓存MapperMethod对象methodCache
返回值是否是游标
判断是否开启二级缓存cache是否为空
mapKey = getMapKey(method)方法的返回值是Map且制定了@MapKey注解就使用getMapKey方法处理
class不为空
executeForMap返返回值是map
在设置执行器Executor时,会判断当前操作是否需要缓存操作,如果需要,把选择好的执行器Executor放到CachingExecutor中去CachingExecutor:二级缓存执行器
执行具体的方法
返回值是否是集合和数组
根据select节点的配置,决定是否需要清空二级缓存
解析typeAliases属性
为MapperMethod对象相关属性赋值
解析方法的返回值类型
doQuery实际干活的方法
selectList获取结果的时候只获取一个
调用XmlMapperBulider对象的XmlPathParser对象进行mapper.xml配置文件的解析
handler.query(.....)使用sql语句处理器调用query方法执行sql语句,并通过ResultSetHandler完成结果集的映射
创建SqlCommand对象为其属性赋值用于存储当前sql语句的类型信息
根据CacheKey从一级缓存(localCache)中获取当前sql语句的结果。
resolveMappedStatement获取当前sql语句的类型以及sql语句的相关信息
有
PREPARED
没有
创建XmlConfigBuilder对象,此对象用于构建SqlSessionFactory对象,中间涉及到document对象的创建以及具体参数的解析。
为name与type属性值赋值
创建CacheKey对象,mybatis默认有一级缓存,设置一级缓存名称
为sqlSession对象的相关参赋值
移除一级缓存localCache中的占位符
buildStatementFromContext构建sql语句
将statement对象转成PreparedStatement然后调用方法execute完成具体的数据库操作
判断StatementType的类型
关闭自动提交
m.isDefault()判断该接口方法是不是默认的
调用loadXmlResource()方法对mapper.xml文件进行解析
解析objectFactory属性
解析databaseIdProvider属性
创建MapperAnnotationBuilder对象,调用parse()方法,对接口对应的mapper.xml配置以及sql相关注解进行解析
executor.query()调用执行
handleRowValues对ResultSet进行映射,并将映射得到的结果对象添加到DefaultResultHandler对象中暂存
在MapperRegistry.getMapper()的knownMappers中获取对应接口的MapperProxyFactory映射器代理工厂对象knownMappers在configuration中
4.通过builder方法构建创建出sqlSessionFactory对象,方便后续对数据库进行操作
判断方法的返回值是否OptionalreturnsOptional
解析typeHandlers属性
解析objectWrapperFactory属性
执行invoke方法里面的execute方法
查询结束
resource、url、classs三个属性是否为空
doQuery()调用doQuery方法完成数据库查询,并得到映射后的结果对象
创建XmlMapperBulider对象,解析对应的mapper.xml配置文件
STATEMENT
prepareStatement()
解析plugins属性
执行器一般有三种
ReuseExecutor可重用的执行器
通过sqlSession.getMapper方法获取具体Mppar对象
解析mappers属性
设置Environment对象
包含了具体的sql的操作
创建MethodSignature对象为其属性赋值用于存放mappaeer接口方法的返回值信息
创建Statement对象
parseConfiguration方法
执行cachedInvoker方法创建MapperMethodInvoker对象
resource或者url不为空
创建PreparedStatementHandler对象
handleRowValuesForSimpleResultMap单一结果的处理
创建SimpleStatementHandler对象
创建XmlPathParser对象,解析具体的xml文件
将结果集封装成ResultSetWrapper对象然后返回
建造者模式
selectinsertupdatedelete
handleRowValuesForNestedResultMap嵌套结果的处理
newInstance创建MapperProxy对象,每次调用都会创建新的mapperProxy对象
1.为某些参数设置默认值
1.将解析后sql信息设置到MappedStatement对象中
RoutingStatementHandler对象的属性delegate赋值
1.获取mapper节点的namespace属性
处理sql语句的占位符
insert
抛异常
handleResultSets()获取具体的结果集,只不过是字节数组,需要把这些字节数组转成实际的实体对象
selectOne获取单个结果
解析@Flush注解
2.处理sql语句的类型
queryFromDatabase()从数据中获取
创建DefaultSqlSession对象作为sqlSession对象
1.mybatis-config.xml
在一级缓存localCache中添加占位符
直接跳过
执行query方法直接查询
select
判断SQL节点的useCache配置以及是否使用了resultHandler配置
是否有返回值与resultHandlerIndex不等于空
封装了mybatis在运行过程中需要的所有参数,有些是参数有默认值,有些参数没有默认值,需要在后续过程中进行赋值操作的
对mybatis-config.xml配置文件的每一个属性都进行详细的解析,解析完成之后,把需要的属性值,设置到configuration对象中
设置sqlSession对象sqlSession
2.加载
创建PlainMethodInvoker对象并为其相关属性赋值
executeWithResultHandler有结果处理器
2.初始化类型处理器注册器
getResultSet()获取第一个结果集并且判断是否为空
调用构造方法来进行对象创建,再创建的时候,会创建一个全局configuration对象
一系列elemet元素的解析
4.调用XmlConfigBuilder对象的XmlPathParser对象进行xml配置文件的解析
进行数据库连接获取connection对象
为MapperProxy对象的相关参赋值
创建MapperMethod对象用于保存保存对应接口方法的SQL以及入参和出参的数据类型等信息
创建CallableStatementHandler对象
查询一级缓存是否有结果集
一般都是SimpleExecutor
0 条评论
下一页