当前位置: 首页 > news >正文

MyBatis总结(2)- MyBatis实现原理(一)

Mybatis实现原理:

概括一句话:约定配置参数mybatis-config.xml,映射关系JavaBean-mapper.xml,用SqlSessionFactoryBuilder构建应用程序运行期间需要的SqlSessionFactory实例对象,当请求或方法需要执行CURD操作时,通过SqlSessionFactory创建一个SqlSession对象,来进行对数据库的操作。

核心类

  • SqlSessionFactoryBuilder
  • SqlSessionFactory
  • SqlSession

Mybatis核心类作用:

SqlSessionFactoryBuilder:

- 作用?
  • 只做一件事情:用来构建SqlSessionFactory实例
- 基于什么构建?
  • mybatis-config xml配置,抑或是自定义Configuration实例对象
- 生命周期?
  • 构建完Factory实例,即可销毁,作用域一般在方法中作为局部变量使用

SqlSessionFactory:

- 作用?
  • 用来“加工生产”SqlSession实例对象
- 基于什么构建?
  • 基于SqlSessionFactoryBuilder在建造时解析出来的Configuration对象(会包含environment, properties, setting, mappers映射关系等)
    在这里插入图片描述
    • 而这个Configuration对象就是在SqlSessionFactoryBuilder构造build时,通过XmlConfigBuilder将我们定义好的mybatis-config.xml配置文件解析成程序对象,具体是通过这个方法org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration处理的:

      • 从这里可以看出,在xml中的xml标签(properties, typeAliases等等),这就理解了设置标签时的规则【Q1】:
private void parseConfiguration(XNode root) {try {// issue #117 read properties firstpropertiesElement(root.evalNode("properties"));Properties settings = settingsAsProperties(root.evalNode("settings"));loadCustomVfsImpl(settings);loadCustomLogImpl(settings);typeAliasesElement(root.evalNode("typeAliases"));pluginsElement(root.evalNode("plugins"));objectFactoryElement(root.evalNode("objectFactory"));objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));reflectorFactoryElement(root.evalNode("reflectorFactory"));settingsElement(settings);// read it after objectFactory and objectWrapperFactory issue #631environmentsElement(root.evalNode("environments"));databaseIdProviderElement(root.evalNode("databaseIdProvider"));typeHandlersElement(root.evalNode("typeHandlers"));mappersElement(root.evalNode("mappers"));} catch (Exception e) {throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);}}
- 生命周期?
  • 一旦被构建,应该在程序运行期间一直存在,且一般情况下,都是以单例存在,不需要创建多个。作用域应该为应用作用域。

SqlSession

- 作用?
  • 用来处理执行sql CURD操作,事务管理,以及缓存功能
- 基于什么构建?
  • 每当SqlSessionFactory对象调用openSession方法时,就会创建一个DefaultSqlSession实例对象;
  • 该SqlSession对象会有一个属性为Executor对象,而这个Executor对象是基于Environment配置中定义的transactionManager 类型type创建起来的(一般情况下是:JdbcTransaction)。最终的代码逻辑为:
    • 获取JavaBean Mapper对象,通过SqlSession的Configuration对象中获取预先定义好的mappers,根据映射id,找到MappedStatement;

    • 执行CURD操作,通过SqlSession的Executor【Q2】对象来受理数据库操作,最终是交给JDBCTransaction事务对象完成的
      在这里插入图片描述

    • 拿到JavaBean的Mapper对象后,根据method方法名查找mapper映射信息:
      在这里插入图片描述

    • 在mapper映射中创建一个个CURD,都会被解析成一个个以 id 为key,以MappedStatement为value的map.entry对象:
      在这里插入图片描述

    • 而这里的MappedStatement对象:属于Prepared类型的,且将我们在mapper定义的信息加载出来,在这里可以理解为是一个信息库,供后续sql交互时使用:
      在这里插入图片描述

    • 最终执行sql时,还是回到了熟悉的JDBC配方:
      这个SimpleExecutor继承了我们SqlSession的Executor对象,通过transaction去创建Connection,去创建preparedStatement,得到结果集ResultSet:
      在这里插入图片描述在这里插入图片描述

  • 画个图更清晰些:
    Mybatis核心原理

- 生命周期?

  • 每个线程都应该有它自己的 SqlSession 实例。一般情况下,作用域是请求或方法作用域,一次Http请求,或一个方法的CURD操作。注意一点的是,这里需要显式的事务管理,缺省值autocommit为false。另外一点的是,用完需要关闭资源。

【Q1】: 这里标签的编写是有顺序要求的:

  • 必须按照要求的顺序来:
The content of element type "configuration" must match"(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)".

【Q2】: 这里Excutor,在OpenSqlSession创建时,就可以看到:(具体会在后续总结到)

  • SqlSession -> Executor = CachingExecutor(在Cache中查询信息)
  • CachingExecutor -> Delegate(委托代理) = BaseExecutor(真正去DB操作的执行器对象)
    • 这里就涉及到Mybatis的缓存功能:
      • Mybatis分为:
        • 一级缓存: 默认开启,SqlSession级别;
        • 二级缓存:Mapper级别,需要在mapper映射上定义<cache>标签来开启

相关文章:

  • python绘制piper三线图
  • 如何更精准定位你的Facebook广告受众?
  • 【GD32F303红枫派使用手册】第九节 RTC-万年历实验
  • 深入理解feign远程调用的各种超时参数
  • 大模型训练学习笔记
  • 网络协议三
  • 蓝桥杯物联网竞赛_STM32L071_19_输出方波信号(PWM)
  • Sketch文件轻松转换为PSD的简便方法
  • 轻松解决问题!教你文件怎么解除只读模式!
  • 史上最易懂的mysql锁 、mvvc分析
  • QFD(质量功能展开)是怎么使产品满足用户需求的?
  • 隐藏 IP 地址的重要性是什么?
  • 2024年华为OD机试真题-万能字符单词拼写-Java-OD统一考试(C卷D卷)
  • 关闭windows11磁盘地址栏上的历史记录
  • 论文敲公式敲到“崩溃”?合合信息扫描全能王“公式识别”一键解决公式提取难题
  • 【node学习】协程
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • CentOS7 安装JDK
  • Facebook AccountKit 接入的坑点
  • Java 最常见的 200+ 面试题:面试必备
  • JAVA_NIO系列——Channel和Buffer详解
  • JavaScript DOM 10 - 滚动
  • Java的Interrupt与线程中断
  • JS学习笔记——闭包
  • React as a UI Runtime(五、列表)
  • ReactNativeweexDeviceOne对比
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • Sublime Text 2/3 绑定Eclipse快捷键
  • Vue.js源码(2):初探List Rendering
  • vue--为什么data属性必须是一个函数
  • webpack+react项目初体验——记录我的webpack环境配置
  • 缓存与缓冲
  • 蓝海存储开关机注意事项总结
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 微信小程序填坑清单
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 走向全栈之MongoDB的使用
  • Java性能优化之JVM GC(垃圾回收机制)
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • ​渐进式Web应用PWA的未来
  • ​香农与信息论三大定律
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • #etcd#安装时出错
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (ZT)薛涌:谈贫说富
  • (附源码)springboot电竞专题网站 毕业设计 641314
  • (已解决)什么是vue导航守卫
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .bat批处理(六):替换字符串中匹配的子串
  • .net core 连接数据库,通过数据库生成Modell
  • .net快速开发框架源码分享
  • .NET与 java通用的3DES加密解密方法
  • /usr/bin/python: can't decompress data; zlib not available 的异常处理