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

MyBatis 的工作原理解析

文章目录

  • 前言
  • 一、mybatis工作原理
    • 1.1 流程图
    • 1.2 步骤解析
    • 1.3 代码实现

前言

本文记录 Mybatis 的工作原理,做到知识梳理总结的作用。

一、mybatis工作原理

Mybatis 的总体工作原理流程图如下图所示

1.1 流程图

在这里插入图片描述

1.2 步骤解析

Mybatis 框架在工作时大致经过8个步骤,如下:

  1. 读取 Mybatis 配置文件 mybatis-config.xml,该配置文件作为 Mybatis 的全局配置文件,配置了 Mybatis 的运行环境和数据库连接等信息。

  2. 加载映射文件 mapper.xml,该文件中配置了操作数据库的 sql 语句,需要在mybatis-config.xml中加载才能执行。mybatis-config.xml 可以加载多个配置文件,每个配置文件对应数据库中的一张表。

  3. 通过 SqlSessionFactoryBuilder 对象的 build() 方法构建会话工厂,且 build() 方法参数为 mybatis-config.xml 配置文件的输入流,通过 Mybatis 的环境等配置信息构建会话工厂 SqlSessionFactory - 工厂设计模式。

//build方法源码:将mybatis-config.xml 配置文件输入流解析成xml配置对象
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
  1. 创建 SqlSession 对象,由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 的所有方法。

  2. Mybatis 的底层定义了一个 Executor 接口来操作数据库,它会根据 SqlSession 传递的参数动态的生成需要执行的 SQL 语句,同时负责查询缓存的维护。

  3. 在 Executor 接口的方法中,包含一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等。Mapper.xml 文件中的一个SQL对应一个 MappedStatement 对象,SQL 的 id 即是 MappedStatement 的 id。

  4. 输入映射参数,在执行方法时 MappedStatement 对象会对用户执行 SQL 语句的输入参数进行定义(可以定义为 Map、List 类型、基本类型和 POJO 类型),Executor 执行器会通过 MappedStatement 对象在执行 SQL 前,将输入的 java 对象映射到 SQL 语句中。这里对输入参数的映射过程就类似于 JDBC 编程中对 preparedStatement 对象设置参数的过程。

  5. 输出结果映射,在数据库中执行完SQL语句后 MappedStatement 对象会对 SQL 执行输出的结果进行定义(可以定义为 Map、List 类型、基本类型、POJO类型),Executor 执行器会通过 MappedStatement 对象在执行 SQL 语句后,将输出结果映射到 java 对象中。这种将输出结果映射到 java 对象的过程就类似于 JDBC 编程中对结果的解析处理过程。

1.3 代码实现

mybatis 数据库的 user 表数据

在这里插入图片描述

Mybatis 的 mybatis-config.xml 配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;useUnicode=false&amp;characterEncoding=utf8;serverTimezone=GMT%2B8"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments><!--每一个Mapper.xml都需要在mybatis核心配置文件中注册--><mappers><!--resource要用 /--><mapper resource="com/kuang/dao/UserMapper.xml"/></mappers>
</configuration>

MybatisUtils 获取 sqlSession 对象工具类

public class MybatisUtils {private static SqlSessionFactory sqlSessionFactory;static{try {//访问mybatis 读取User数据//mybatis全局配置文件名定义String resource = "mybatis-config.xml";//读取这个resource表示的文件并将其转化为输入流InputStream inputStream = Resources.getResourceAsStream(resource);//sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {e.printStackTrace();}}/***既然有了SqlSessionFactory顾名思义,我们可以从其中获得SqlSession的实例了* Session完全包含了面向数据库执行sql命令的所有方法*/public static SqlSession getSqlSession(){return sqlSessionFactory.openSession();}
}

UserMapper 操作数据库的方法定义

public interface UserMapper{/***查询全部用户*/List<User> getUserList();/***根据id查询用户 传递参数id*/User getUserById(int id);
}    

UserMapper.xml 操作数据库的 SQL 语句

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.dao.UserMapper">
<!-- id就是UserMapper中的方法名  resultType sql语句的返回值类型  parameterType参数类型--><select id="getUserList" resultType="com.kuang.pojo.User">select *from mybatis.user;</select><select id="getUserById" parameterType="int" resultType="com.kuang.pojo.User">select *from mybatis.user where id = #{id};</select>
</mapper>    

获取所有数据,单元测试

@Test
public void test() {//获得SqlSession对象SqlSession sqlSession = MybatisUtils.getSqlSession();try{//方式一:获得getMapperUserMapper userDao = sqlSession.getMapper(UserMapper.class);List<User> userList = userDao.getUserList();for (User user : userList) {System.out.println(user);}} catch (Exception e) {e.printStackTrace();}finally{//关闭sqlsqlSession.close();}
}

测试结果

在这里插入图片描述
根据 id 获取用户数据,单元测试

@Test
public void getUserById(){//获得SqlSession对象SqlSession sqlSession = MybatisUtils.getSqlSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);User user = mapper.getUserById(3);System.out.println(user);//关闭sqlsqlSession.close();
}

测试结果
在这里插入图片描述

相关文章:

MyBatis 的工作原理解析

文章目录前言一、mybatis工作原理1.1 流程图1.2 步骤解析1.3 代码实现前言 本文记录 Mybatis 的工作原理&#xff0c;做到知识梳理总结的作用。 一、mybatis工作原理 Mybatis 的总体工作原理流程图如下图所示 1.1 流程图 1.2 步骤解析 Mybatis 框架在工作时大致经过8个步骤…...

终端软件架构说

目录 零&#xff1a;前言 一&#xff0c;基于服务的架构 二&#xff0c;基于多进程多线程的架构 三&#xff0c;以数据为中心的架构 四&#xff0c;类Android的分层架构设计 五&#xff0c;总结 零&#xff1a;前言 谈到架构&#xff0c;可能大家的第一感觉是信息系统的…...

LearnOpenGL-入门-你好,三角形

本人刚学OpenGL不久且自学&#xff0c;文中定有代码、术语等错误&#xff0c;欢迎指正 我写的项目地址&#xff1a;https://github.com/liujianjie/LearnOpenGLProject LearnOpenGL中文官网&#xff1a;https://learnopengl-cn.github.io/ 文章目录图形渲染管线基本介绍着色器…...

SOEM 源码解析 ecx_init_redundant

/* Initialise lib in redundant NIC mode* 在冗余网卡模式下初始化lib库* param[in] context context struct* 上下文结构体* param[in] redport pointer to redport, redundant port data* 指向冗余端口的指针&#xff…...

网页唤起 APP中Activity的实现原理

疑问的开端大家有没有想过一个问题&#xff1a;在浏览器里打开某个网页&#xff0c;网页上有一个按钮点击可以唤起App。这样的效果是怎么实现的呢&#xff1f;浏览器是一个app&#xff1b;为什么一个app可以调起其他app的页面&#xff1f;说到跨app的页面调用&#xff0c;大家是…...

【操作系统】概述

基本特征 1. 并发 并发是指宏观上在一段时间内能同时运行多个程序&#xff0c;而并行则指同一时刻能运行多个指令。 并行需要硬件支持&#xff0c;如多流水线、多核处理器或者分布式计算系统。 操作系统通过引入进程和线程&#xff0c;使得程序能够并发运行 2. 共享 共享…...

Flume三种组件的选择对比

文章目录1.source2.channel3.sink1.source Source: 数据源:通过source组件可以指定让Flume读取哪里的数据&#xff0c;然后将数据传递给后面的 channel Flume内置支持读取很多种数据源&#xff0c;基于文件、基于目录、基于TCP\UDP端口、基于HTTP、Kafka的 等等、当然了&#x…...

响应性基础API

一.什么是proxy和懒代理&#xff1f;什么是proxy?proxy对象是用于定义基本操作的自定义行为(如&#xff1a;属性查找&#xff0c;赋值&#xff0c;枚举&#xff0c;函数调用等等)。什么是懒代理&#xff1f;懒代理&#xff1a;在初始化的时候不会进行全部代理&#xff0c;而是…...

剑指 Offer 25. 合并两个排序的链表

剑指 Offer 25. 合并两个排序的链表 难度&#xff1a;easy\color{Green}{easy}easy 题目描述 输入两个递增排序的链表&#xff0c;合并这两个链表并使新链表中的节点仍然是递增排序的。 示例1&#xff1a; 输入&#xff1a;1->2->4, 1->3->4 输出&#xff1a;1…...

顿悟日记(一)

目录2023年1月顿悟日记&#xff1a;2023年2月24日顿悟日记&#xff1a;2023年2月25日顿悟日记&#xff1a;2023年2月26日顿悟日记&#xff1a;顿悟的经历是如此的奇妙&#xff0c;且让人亢奋的事情。 2023年1月顿悟日记&#xff1a; 1.我是面向对象还是面向过程&#xff1f; …...

前端卷算法系列(二)

前端卷算法系列&#xff08;二&#xff09; 回文数 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样…...

网络应用之HTTP响应报文

HTTP响应报文学习目标能够知道HTTP响应报文的结构1. HTTP响应报文分析HTTP 响应报文效果图:响应报文说明:--- 响应行/状态行 --- HTTP/1.1 200 OK # HTTP协议版本 状态码 状态描述 --- 响应头 --- Server: Tengine # 服务器名称 Content-Type: text/html; charsetUTF-8 # 内容类…...

常见的CSS技巧

1.禁止长按图片弹出菜单 img {-webkit-touch-callout: none; // 主要用于禁止长按菜单。主针对webkit内核的浏览器&#xff1b; } /*或者 user-select , 是css3的新属性&#xff0c;用于设置用户是否能够选中文本*/ .img {-webkit-user-select: none;-khtml-user-select: none…...

算法进阶-动态规划

经典例题 大家肯定想用递归做 思路大概就是这样 递归到最后一行就是对应的D(i,j) 然后往上推 但是这样会超时&#xff0c;因为存在大量的重复计算 比如调用第一行MasSum(7)需要调用MaxSum(3)和MaxSum(8) 但是调用第二行MaxSum(3)还要调用3行的MaxSum(8)和3行的MaxSum(1) 第二行…...

python的读写操作

一、使用open函数&#xff0c;可以打开一个已经存在的文件&#xff0c;或着创建一个新文件 语法如下&#xff1a; open(name, mode, encoding) name: 要打开的目标文件的字符串(可以包含文件所在的具体路径) mode: 打开文件模式&#xff1a;只读(r)、写入(w)、追加(a)等 e…...

Mybatis中添加、查询、修改、删除

在Mybatis中添加数据的操作 编写相对应的SQL语句&#xff0c;并完成相关数据的对应关系 编写测试用例 需要提交事务 sqlSession commit() 这里需要注意的是mybatis是默认的是手动提交事务&#xff0c;如果不写的话会进行回滚&#xff0c;添加操作就不会被执行 或者在 如果…...

C++---线性dp---传纸条(每日一道算法2023.2.26)

注意事项&#xff1a; 本题dp思路与 “线性dp–方格取数” 一致&#xff0c;下方思路仅证明为什么使用方格取数的思路是正确的。 题目&#xff1a; 小渊和小轩是好朋友也是同班同学&#xff0c;他们在一起总有谈不完的话题。 一次素质拓展活动中&#xff0c;班上同学安排坐成…...

浅谈 C/C++ 的输入输出

更好的阅读体验\huge{\color{red}{更好的阅读体验}}更好的阅读体验 文章目录0. 叠甲&#xff0c;过1. 谈谈输入输出缓冲区1.1 基本概念输入输出流标准输入输出流文件输入输出流1.2 输入输出缓冲区什么是输入输出缓冲区&#xff1f;为什么要设置输入输出缓冲区&#xff1f;C/C 的…...

【计算机三级网络技术】 第二篇 中小型系统总体规划与设计

文章目录一、基于网络的信息系统基本结构二、划分网络系统组建工程阶段三、网络需求调研与系统设计原则四、网络用户调查与网络工程需求分析1.网络用户调查2.网络节点的地理位置分布3.应用概要分析4.网络需求详细分析五、网络总体设计基本方法1.网络工程建设总体目标与设计原则…...

Boosting Crowd Counting via Multifaceted Attention之人群密度估计实践

这周闲来无事&#xff0c;看到一篇前不久刚发表的文章&#xff0c;是做密集人群密度估计的&#xff0c;这块我之前虽然也做过&#xff0c;但是主要是基于检测的方式实现的&#xff0c;这里提出来的方法还是比较有意思的&#xff0c;就拿来实践一下。论文在这里&#xff0c;感兴…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...