mybatis 原理_了解Mybatis的工作原理吗

本文详细解析了Mybatis从创建SqlSessionFactory到执行SQL请求的全过程,涉及SqlSessionExecutor、StatementHandler和相关组件。重点介绍了Mapper配置、SqlStatement构建、缓存管理和执行策略,适合深入理解Mybatis内部机制。
摘要由CSDN通过智能技术生成

ba13b106306b0b7c162f906f13448d14.png
作者:江南入直 http:// cnblogs.com/scuury/p/10 371246.html

推荐阅读

1. SpringBoot 整合篇

2. 手写一套迷你版HTTP服务器

3. 记住:永远不要在MySQL中使用UTF-8

4. Springboot启动原理解析

近来想写一个mybatis的分页插件,但是在写插件之前肯定要了解一下mybatis具体的工作原理吧,于是边参考别人的博客,边看源码就开干了。

核心部件:

  • SqlSession
  • Executor
  • StatementHandler
  • ParameterHandler
  • ResultSetHandler
  • TypeHandler
  • MappedStatement
  • Configuration

在分析工作原理之前,首先看一下我的mybatis全局配置文件

<?

第一步:创建一个sqlSessionFactory

在了解如何创建sqlSessionFactory之前,先看一下mybatis是如何加载全局配置文件,解析xml文件生成Configuration的

public 
private 

在上面的第二段代码中有一句

mapperElement(root.evalNode("mappers"));

刚好我们的全局配置文件中有一个mapper的配置,由此可见,mapperElemet()方法是解析mapper映射文件的,具体代码如下

private 

根据以上代码可以分析,在写mapper映射文件的地址时不仅可以写成resource,还可以写成url和mapperClass的形式,由于我们用的是resource,所以直接进入第一个判断,最后解析mapper映射文件的方法是

private 

其中具体解析每一个sql语句节点的是

buildStatementFromContext(context.evalNodes("select|insert|update|delete"));

进入这个方法一层层深究,最后到这里可以知道MappedStatement是由builderAssistant(即MapperBuildAssistant)创建的。

public 

最后进入方法addMappedStatement(),mappedStatement最后以id为键保存在了Configuration中的一个map变量mappedStatements中。

public 

最后回到我们的创建sqlSessionFactory上,之前的一切都是为了生成一个sqlSessionFactory服务的

public 

从上面的代码可以看出最后是通过以Configuration为参数build()方法生成DefautSqlSessionFactory。

第二步:创建sqlSession

public 
private 
//返回一个SqlSession,默认使用DefaultSqlSession 

executor在这一步得到创建,具体的使用在下一步。

第三步:执行具体的sql请求

在我的代码里执行的是

User 

具体到里面的方法就是

public 

在这里通过statementId拿到了我们在第一步存在map里面的MappedStatement。在这里引用参考博客的一句话:

SqlSession根据Statement ID, 在mybatis配置对象Configuration中获取到对应的MappedStatement对象,然后调用mybatis执行器来执行具体的操作。

再继续看query()和queryFromDatabase()这两个方法

@SuppressWarnings
private 

在这两个方法里面会为当前的查询创建一个缓存key,如果缓存中没有值,直接从数据库中读取,执行查询后将得到的list结果放入缓存之中。

紧接着看doQuery()在SimpleExecutor类中重写的方法

public 

Statement连接对象就是在这里创建的,因此Executor的作用之一就是创建Statement了,创建完后又把Statement丢给StatementHandler返回List查询结果。

接下来再看一下这里的两个方法prepareStatement()和query()的具体实现

private 
public 

prepareStatement()是创建Statement的具体实现方法,调用parameterize()对创建的Statement对象设置参数,即为我们设为占位符的地方赋上指定的参数,parameterize()方法再深入进去就是调用ParameterHandler的setParameters()方法具体赋值了。

这里的query()是调用了ResultSetHandler的handleResultSets(Statement) 方法。作用就是把ResultSet结果集对象转换成List类型的集合。

总结以上步骤就是:

  1. 根据具体传入的参数,动态地生成需要执行的SQL语句,用BoundSql对象表示
  2. 为当前的查询创建一个缓存Key
  3. 缓存中没有值,直接从数据库中读取数据
  4. 执行查询,返回List 结果,然后 将查询的结果放入缓存之中
  5. 根据既有的参数,创建StatementHandler对象来执行查询操作
  6. 将创建Statement传递给StatementHandler对象,调用parameterize()方法赋值
  7. 调用StatementHandler.query()方法,返回List结果集

总结

以上三个步骤所有流程大体可以用一张图来总结

2227d0a0c7d7777132f3c3281ae51298.png

参考

https:// blog.csdn.net/luanlouis /article/details/40422941 https:// blog.csdn.net/a41245184 8/article/details/82723754
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值