1、初始化SqlSessionFactory,默认实现是DefultSqlSessionFactory,这个一般是一个应用一个实例就够了,例如单例模式;

2、通过SqlSessionFactory获得SqlSession,默认实现是DefaultSqlSession,这个应用范围是一次数据库操作,可以简单理解为JDBC操作的Connection,数据库操作执行完,需要调用close方法手动关闭连接;
3、通过SqlSession可以直接执行数据库操作,这个接口已经定义了许多的常用的操作,例如查询一个对象,查询列表数据,更新操作等等,这里先不做详细介绍。现在MyBatis经常就是跟Spring进行结合使用,MyBatis比ibatis最显著的一个升级,应该就是MyBatis可以不用写Dao接口的实现类,直接通过SqlSession.getMapper(Class clz)方法获得Dao接口的代理类(通过Spring的IOC框架管理Dao接口,实际上依赖注入的时候也是通过MyBatis内部的该方法获得实际的Dao代理对象);
4、生成的Dao接口的代理类是通过MapperProxy.newMapperProxy(Class daoInterface,SqlSession sqlSession)生成的,这个是个静态方法,实现原理是使用了JDK的动态代理机制。SO,MapperProxy是实现了InvocationHandler的类,执行数据库操作的入口就是MapperProxy的invoke方法触发的,再看下该方法,可以知道最终是通过MapperMethod.execute(Object[] params)执行数据库操作;
5、在MapperMethod的构造方法里面,会进行被代理接口的执行的那个方法的信息的读取,比如方法名称(以便后来对应到具体的配置文件的具体语句sqlId)、方法参数(以便对具体的sql语句进行参数替换)等等。然后看下execute方法,根据刚刚初始化的配置信息,判断该次执行是select还是update或者delete操作,转了半天发现,最终还是调用了SqlSession的select、update等方法;
6、好吧,现在回到DefaultSqlSession,以一次查询为例子,最终执行的方法是selectList(String statement, Object parameter, RowBounds rowBounds),参数分别是接口对应的方法名称(会对应到具体的sql上),接口方法参数,返回记录范围(一般没啥用了,分页啥的都是分页语句实现了,不会把所有数据都查出来然后再进行数据范围的筛选)。然后发现最终执行查询的是Executor的query方法,这个执行器是DefaultSqlSession的一个成员变量,默认实现是SimpleExecutor,继承了BaseExecutor,query方法就是在该基类中的。
7、现在到BaseExecutor的query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler)方法里面来,这个是执行查询的入口,这里的第一个参数要说明下,MapperStatement,直接翻译就是映射声明,是对映射信息的封装对象,用来存储记录要映射的sql语句的id、sql语句、传参等等,这个类有个比较重要的方法就是getBoundSql(Object parameterObject),也就是获取绑定的sql,如果要开发一个分页的插件,要利用反射机制,对这个BoundSql进行修改。
8、再回到BaseExecutor的query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler)方法里面来,可以看到最终是调用了内部的query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)方法,在该方法里面发现,如果这次查询是有缓存,则只需从缓存里面取出结果集返回,那这次的查询就结束了。如果没有缓存,那就从数据库里面查询,层层跟踪下去,发现执行的是一个抽象方法doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql),这个方法是由子类实现的,也就是说,我们终于可以回到SimpleExecutor了;
9、回到SimpleExecutor的doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql),在这个方法里面,会选择具体的执行StatementHandler,这是个接口,是通过Configuration的newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)方法获取具体的处理器,并且根据配置文件中的插件,加工StatementHandler,实际上使用的也是JDK的代理机制,如果有添加插件的话,这个StatementHandler也是个代理对象(最常见的分页插件);
10、介绍下StatementHandler,看见Statement,想必有用过java的JDBC操作的都很熟悉这个名字,那实际上Statementhandler就是MyBatis的自己的Statement,用来对数据库进行操作用的。这个接口的是实现类有5个:RoutingStatementHandler,SimpleStatementHandler,PreparedStatementHandler,CallableStatementHandler,BaseStatementHandler。
  • RoutingStatementHandler:StatementHandler的路由选择,根据配置文件里面的信息,判断具体选择SimpleStatementHandler,PreparedStatementHandler,CallableStatementHandler三个里面的哪个StatementHandler,它有个成员变量StatemenHandler delegate,这个delegate就是选择的具体的StatementHandler;
  • SimpleStatementHandler:即使用JDBC的Statement进行数据库操作;
  • PreparedStatementHandler:即使用JDBC的PreparedStatement进行数据库操作,一般的配置都是使用这个,预处理语句进行数据库操作;
  • CallableStatementHandler:即使用JDBC的CallableStatement进行数据库操作;
  • BaseStatementHandler:SimpleStatementHandler、PreparedStatementHandler、CallableStatementHandler的父类。
11、现在获取了的具体的StatementHandler后,我们以常用的PreparedStatementHandler为例,然后就是根据配置的信息,参数等对这个handler内部的PreparedStatement进行操作了,也就是JDBC中我们经常做的参数set啥的了,这里就不做介绍了,可以认为StatementHandler就是对JDBC的Statement以符合MyBatis配置的要求进行一次包装,最终对数据库进行操作的,还是JDBC中的Statement(PreparedStatement继承自Statement)。
12、数据库操作就执行结束了,然后就是关闭连接了,就不说了~
PS:大家可以结合该文章,对源代码进行跟踪,可以更方便的理解其中的原理

MyBatis执行一次数据库操作的原理以及顺序相关推荐

  1. spring boot 入门_SpringBoot入门建站全系列(三十)Mybatis多数据源进行数据库操作

    SpringBoot入门建站全系列(三十)Mybatis多数据源进行数据库操作 一.概述 多数据源,就是有多个数据库的配置. 多数据源配置并不麻烦,使用起来和单数据源基本相同,但是,重要的是事务的控制 ...

  2. 使用Memcache缓存mysql数据库操作的原理和缓存过程浅析

    1.首先明确是不是一定要上缓存,当前架构的瓶颈在哪里,若瓶颈真是数据库操作上,再继续往下看. 2.明确memcached和redis的区别,到底要使用哪个.前者终究是个缓存,不可能永久保存数据(LRU ...

  3. 利用Mybatis写第一个数据库操作的程序

    文章目录 mybatis下载 业务需求 环境搭建 加入配置文件 创建pojo sql映射文件 加载映射文件 实现根据id查询用户 测试程序: 效果 mybatis下载 mybaits的代码由githu ...

  4. Mybatis新发现—在idea中数据库操作出现了异常,最好的查错助手居然是这个!

    Mybatis新发现--如果一个数据库操作出现了异常,最好的助手居然是这样! 1. 日志工厂 如果一个数据库操作出现了异常,我们需要排错.日志就是最好的助手. 曾经:sout,debug 现在:日志工 ...

  5. MyBatis 源码阅读 -- 核心操作篇

    核心操作包是 MyBatis 进行数据库查询和对象关系映射等工作的包.该包中的类能完成参数解析.数据库查询.结果映射等主要功能.在主要功能的执行过程中还会涉及缓存.懒加载.鉴别器处理.主键自增.插件支 ...

  6. sql备份恢复数据库_使用DBATools通过SQL恢复数据库操作验证备份

    sql备份恢复数据库 In this article, we will explore database backup validation by with SQL restore database ...

  7. 【数据库】(三)-- mysql 数据库操作应用

    [数据库](三)-- mysql 数据库操作应用 操作说明 使用 navicat 针对 mysql 进行 sql 的使用,mysql 运行在本地的 docker 环境的应用容器中. 语法和关键字什么的 ...

  8. java解析sql语句简书,Mybatis原理解析(一)--java.sql数据库操作的基本实现方式

    在研究Mybatis原理之前,先看一下java中是如何实现一次对数据库的访问的: public void testSql() { Connection connection = null; State ...

  9. mybatis 执行插入操作,insert 返回1,数据库中无数据。数据库中数据的创建时间和插入执行时间不一致。

    大家好,我是烤鸭: 今天记录一下线上的问题,由于不是我们组的代码,所以没参与全程,只是最后有幸听各位大佬探讨解决方案.mybatis 执行插入操作,insert返回1,日志记录和接口返回都正常,但是数 ...

最新文章

  1. 【问题收录】Ubuntu(14.04)那些我遇到的各种事
  2. 上海交大c语言第一次作业,上海交大网络学院-计算机第一次作业及答案(含6次机会全部题目)-计算机基础的知识.docx...
  3. package中的常用script命令
  4. C语言 string.h 中函数的实现
  5. 硬件:RS485基础知识笔记
  6. 图像识别_2010暑期实训有感【二】
  7. 大数据下单集群如何做到2万+规模?
  8. 如何学机器计算机,学习编程的你要了解程序是如何被计算机所执行的?
  9. js给php赋值,JavaScript_javascript给span标签赋值的方法,js给span标签赋值的方法?一般 - phpStudy...
  10. Redis数据库15点介绍
  11. 什么样的文章更容易被编辑推荐?
  12. HTML5与HTML4区别
  13. 从计算机复试看中国教育——一个面试官的经历
  14. 巧用代理猎手揪出局域网中的二级代理
  15. IEEE极限编程练习:Sorting Partition
  16. Python利用Reportlab生成PDF文档
  17. XP卸载IE8的方法
  18. (SDL2)SDL在ubuntu下的测试代码(雷霄骅)
  19. utf8编码在线转换html,utf8 gb2312编码在线转换工具
  20. 确定性知识表示法--规则(产生式)表示法

热门文章

  1. 最实用idae快捷键
  2. Excel中引用方法
  3. 运筹说 第85期 | 只有初中学历的数学家
  4. 管理系统页面布局 html,二十五个精美的后台管理界面模板和布局
  5. proteus中仿真D触发器CD4013
  6. L1-007 念数字 (10分) 输入一个整数,输出每个数字对应的拼音。当整数为负数时,先输出fu字。十个数字对应的拼音如下: 0: ling 1: yi 2: er 3: san 4: si 5:
  7. jdk安装及配置超详细图文
  8. 经常说的 CPU 上下文切换是什么意思?
  9. 引用Bootstrap无法显示样式,可能是安装的版本和参考的文档不相符
  10. java毕业生设计校园兼职招聘系统计算机源码+系统+mysql+调试部署+lw