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

MyBatis的运行原理

目录

1、目的:梳理一下MyBatis运行时的几个对象,我们需要搞清楚他们的作用,进而需要理解mybatis的整个工作流程和执行原理。

2、简要概括各个类

2.1 Resources

作用:编写资源加载类,使用类加载器加载 配置文件(mybatis-config.xml ),即:读取mybatis-config.xml

2.2 SqlSessionFactoryBuilder

作用:将配置资源封装成Configuration对象,并且将该资源对象传到工厂对象中

2.2.1 Configuration

作用:配置类 --> 把所有的配置信息 都装进去

2.2.2 MappedStatement

作用:用来封装 sql语句 和 查询结果集(即:返回值类型)

2.3 SqlSessionFactory

2.4 SqlSession

2.5 ProxyFactory

3、测试


1、目的:梳理一下MyBatis运行时的几个对象,我们需要搞清楚他们的作用,进而需要理解mybatis的整个工作流程和执行原理。

mybatis-config.xml

mapper.xml mapper.xml mapper.xml...

|

|

Resources

|

|---->InputStream

|

SqlSessionFactoryBuilder

|

|---->Configuration(conn, Map<namespace+"."+id, MappedStatement(sql, resultType)>)

|

SqlSessionFactory

|

|---->Configuration(conn, Map<namespace+"."+id, MappedStatement(sql, resultType)>)

|

SqlSession

|

|---->conn, Map<namespace+"."+id, MappedStatement(sql, resultType)>

|

ProxyFactory

|

|---->MappedStatement(sql, resultType), conn

|

Executor

| |

| |

| |

输入出映射

2、简要概括各个类

2.1 Resources

作用:编写资源加载类,使用类加载器加载 配置文件(mybatis-config.xml ),即:读取mybatis-config.xml

package com.by.io;import java.io.InputStream;public class Resources {//根据文件名称,加载类路径下面的配置文件public static InputStream getResourceAsStream(String filePath){return Resources.class.getClassLoader().getResourceAsStream(filePath);}
}

2.2 SqlSessionFactoryBuilder

作用:将配置资源封装成Configuration对象,并且将该资源对象传到工厂对象中

package com.by.builder;import com.by.cfg.Configuration;
import com.by.factory.DefaultSqlSessionFactory;
import com.by.factory.SqlSessionFactory;
import com.by.utils.XMLConfigBuilder;import java.io.InputStream;public class SqlSessionFactoryBuilder {/*** 构建SqlSessionFactory对象* @param in* @return*/public SqlSessionFactory build(InputStream in){Configuration configuration = XMLConfigBuilder.loadConfiguration(in);return  new DefaultSqlSessionFactory(configuration);}
}

2.2.1 Configuration

作用:配置类 --> 把所有的配置信息 都装进去

package com.by.cfg;import com.by.mapping.MappedStatement;import java.util.HashMap;
import java.util.Map;public class Configuration {private String driver;private String url;private String username;private String password;/**Map<"com.by.dao.UserDao.findAll", MappedStatement>     */private Map<String, MappedStatement> mappers = new HashMap<String,MappedStatement>();public Map<String, MappedStatement> getMappers() {return mappers;}public void setMappers(Map<String, MappedStatement> mappers) {this.mappers.putAll(mappers);//此处需要使用追加的方式}public String getDriver() {return driver;}public void setDriver(String driver) {this.driver = driver;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}

2.2.2 MappedStatement

作用:用来封装 sql语句 和 查询结果集(即:返回值类型)

package com.by.mapping;public class MappedStatement {private String queryString;//SQLprivate String resultType;//实体类的全限定类名public String getQueryString() {return queryString;}public void setQueryString(String queryString) {this.queryString = queryString;}public String getResultType() {return resultType;}public void setResultType(String resultType) {this.resultType = resultType;}
}

2.3 SqlSessionFactory

package com.by.factory;
public interface SqlSessionFactory {//获取SQLSession对象public SqlSession openSession();
}
package com.by.factory;import com.by.cfg.Configuration;
import com.by.session.DefaultSqlSession;
import com.by.session.SqlSession;public class DefaultSqlSessionFactory implements SqlSessionFactory {private Configuration cfg;public DefaultSqlSessionFactory(Configuration cfg) {this.cfg = cfg;}/*** 获取一个SqlSession对象* @return*/@Overridepublic SqlSession openSession() {return new DefaultSqlSession(cfg);}
}

2.4 SqlSession

public interface SqlSession {//获取代理对象public <T> T getMapper(Class<T> tClass);//释放资源void close();
}
package com.by.session;import com.by.utils.DataSourceUtil;
import com.by.cfg.Configuration;import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;public class DefaultSqlSession implements SqlSession {private Configuration cfg;private Connection conn;public DefaultSqlSession(Configuration cgf){this.cfg = cgf;this.conn = DataSourceUtil.getConnection(cfg);}/** 创建代理对象*/@Overridepublic <T> T getMapper(Class<T> tClass) {/*** tClass.getClassLoader():类加载器* new Class[]{tClass}:Class数组,让代理对象和被代理对象有相同的行为*  new ProxyFactory:调用真实角色,附加自己的操作*/return (T) Proxy.newProxyInstance(tClass.getClassLoader(),new Class[]{tClass},new ProxyFactory(cfg.getMappers(),conn));}@Overridepublic void close() {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}
}

2.5 ProxyFactory

package com.by.session;import com.by.mapping.MappedStatement;
import com.by.utils.Executor;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.Map;public class ProxyFactory implements InvocationHandler {private Map<String, MappedStatement> mappers;private Connection conn;public ProxyFactory(Map<String, MappedStatement> mappers, Connection conn){this.mappers = mappers;this.conn = conn;}//调用代理对象的任何方法,都会在这执行public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//1.获取方法名String methodName = method.getName();//2.获取方法所在类的名称String className = method.getDeclaringClass().getName();//3.组合keyString key = className+"."+methodName;//4.获取mappers中的Mapper对象MappedStatement mappedStatement = mappers.get(key);//5.判断是否有mapperif(mappedStatement == null){throw new IllegalArgumentException("传入的参数有误");}//6.调用工具类执行查询所有return new Executor().selectList(mappedStatement,conn);}
}

3、测试

//1.读取配置文件InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");//2.创建SqlSessionFactory工厂SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();SqlSessionFactory factory = builder.build(in);System.out.println("-----" + factory);//3.使用工厂生产SqlSession对象SqlSession session = factory.openSession();//4.使用SqlSession创建Dao接口的代理对象UserDao userDao = session.getMapper(UserDao.class);//5.使用代理对象执行方法List<User> users = userDao.findAll();for(User user : users){System.out.println(user);}//6.释放资源session.close();in.close();

相关文章:

MyBatis的运行原理

目录 1、目的&#xff1a;梳理一下MyBatis运行时的几个对象&#xff0c;我们需要搞清楚他们的作用&#xff0c;进而需要理解mybatis的整个工作流程和执行原理。 2、简要概括各个类 2.1 Resources 作用&#xff1a;编写资源加载类&#xff0c;使用类加载器加载 配置文件(myb…...

算法题解记录29+++全排列(百日筑基)

一、题目描述 题目难度&#xff1a;中等 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 示…...

苹果AI功能,AI训练数据缺乏,SD3推出,MJ6推出新特性

更多信息&#xff1a; https://agifun.love 智源社区 2024智源大会议程公开丨大模型前沿探索 2024年6月14日-15日&#xff0c;第6届北京智源大会将以线下与线上结合的形式召开&#xff0c;线下会场设在中关村国家自主创新示范区会议中心。2024智源大会再次以全球视野&#x…...

超越中心化:Web3如何塑造未来数字生态

随着技术的不断发展&#xff0c;人们对于网络和数字生态的期望也在不断提升。传统的中心化互联网模式虽然带来了便利&#xff0c;但也暴露出了诸多问题&#xff0c;比如数据滥用、信息泄露、权力集中等。在这样的背景下&#xff0c;Web3技术应运而生&#xff0c;旨在打破传统中…...

【ic-tool】timegen使用

一、前言 TimeGen是一个用于时序波形编辑的CAD工具&#xff0c;它允许数字设计工程师快速有效地绘制数字时序图。TimeGen时序图可以很容易地导出到其他窗口程序&#xff0c;如microsoftword&#xff0c;用于编写设计规范。可直接从官网下载TimeGEN软件&#xff1a;TimeGen Pro…...

1:25万基础电子地图(云南版)

我们在《50幅1:25万基础电子地图&#xff08;四川版&#xff09;》一文中&#xff0c;为你分享过四川的50幅基础电子地图。 现在我们再为你分享云南的1&#xff1a;25万基础电子地图&#xff0c;你可以在文末查看该数据的领取方法。 基础电子地图云南版 下载后可以看到该数据…...

springboot宠物领养系统-计算机毕业设计源码07863

摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存…...

牛客热题:最长回文子串

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 牛客热题&#xff1a;最长回文子串题目链接方法一&am…...

如何访问寄存器

标题 方式一&#xff1a;对地址进行宏定义方式二&#xff1a;用结构体封装寄存器 访问寄存器是CPU执行程序的基础&#xff0c;每种CPU架构都有其特定的寄存器集合和访问方式。 方式一&#xff1a;对地址进行宏定义 #define GPIOA_BASE ((unsigned int)0x48000000) #define GPI…...

苍穹外卖笔记-18-修改密码、bug记录

文章目录 1 修改密码1.1 需求分析和设计1.2 代码实现1.2.1 admin/EmployeeController1.2.2 EmployeeService1.2.3 EmployeeServiceImpl 1.3 功能测试 2 bug记录 1 修改密码 完结的时候发现还有一个接口未实现。这里补充 1.1 需求分析和设计 产品原型&#xff1a; 业务规则&am…...

java如何截取字符串

如果想在一个字符串中截取一段字符&#xff0c;形成新的字符&#xff0c;那么在java中途需要用到substring语句 substring的语法格式是 str.substring(beginindex,endindex) 其中str是字符串 beginindex是起始索引&#xff0c;endindex是结束索引 截取的字符串包含起始索引…...

虚拟淘宝-Virtual-Taobao论文解读(AAAI2019)

目录 1 论文简介 2 文章的主要贡献 3 文章技术的简要说明 4 技术的详细说明 4.1 GAN-SD&#xff1a;生成客户特征 4.2 MAIL&#xff1a;生成交互过程 4.3 ANC&#xff1a;动规范约束 5 实验设定及结果 6 结论 7 参考 1 论文简介 南京大学LAMDA团队的侍竞成、俞扬等…...

低代码组件扩展方案在复杂业务场景下的设计与实践

组件是爱速搭的前端页面可视化模块的核心能力之一&#xff0c;它将前端研发人员从无休止的页面样式微调和分辨率兼容工作中解放了出来。 目前&#xff0c;爱速搭通过内置的上百种功能组件&#xff08;120&#xff09;&#xff0c;基本可以覆盖大部分中后台页面的可视化设计场景…...

震撼科技界的GPT-4o发布首日即遭“越狱破防”

前言 本文主要解读分析OpenAI最新推出的大型模型GPT-4o可能存在的越狱风险。 5 月14 日凌晨的科技圈再一次被OpenAI轰动&#xff0c;其发布的最新大模型GPT-4o&#xff0c;能力横跨语音、文本和视觉&#xff0c;这一成果无疑再次巩固了OpenAI在人工智能领域的领先地位。 然而…...

保护密码安全,探讨密码加盐及其在Go语言中的实现

介绍 在当今数字化时代&#xff0c;个人隐私和数据安全成为了人们关注的焦点之一。随着网络犯罪的不断增加&#xff0c;用户的密码安全性变得尤为重要。密码加盐作为一种常见的安全措施&#xff0c;被广泛应用于密码存储和认证系统中。本文将深入探讨密码加盐的概念、重要性以…...

Sqoop学习详细介绍!!

一、Sqoop介绍 Sqoop是一款开源的工具&#xff0c;主要用于在Hadoop(HDFS/Hive/HBase)与传统的数据库(mysql、postgresql...)间进行数据的传递&#xff0c;可以将一个关系型数据库&#xff08;例如 &#xff1a; MySQL ,Oracle ,Postgres等&#xff09;中的数据导进到Hadoop的H…...

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 生成哈夫曼树(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 生成哈夫曼树(100分) 🌍 评测功能需要订阅专栏后私信联系清…...

ctfshow web 单身杯

web签到 <?phperror_reporting(0); highlight_file(__FILE__);$file $_POST[file];if(isset($file)){if(strrev($file)$file){ //翻转函数include $file;}}要进行反转并且包含文件用data协议 自己写不好写可以用函数帮你翻转 <?php $adata:text/plain,<?eval(…...

天锐绿盾加密软件,它的适用范围是什么?

天锐绿盾数据防泄密软件的适用范围广泛&#xff0c;主要可以归纳为以下几点&#xff1a; 行业适用性&#xff1a; 适用于各个行业&#xff0c;包括但不限于制造业、设计行业、软件开发、金融服务等&#xff0c;特别是对数据安全性要求较高的行业。企业规模与类型&#xff1a; 适…...

mysql面试题 Day2

1 长文本如何存储&#xff1f; 可以使用Text存储 TINYTEXT(255长度) TEXT(65535) MEDIUMTEXT&#xff08;int最大值16M&#xff09; LONGTEXT(long最大值4G) 2 大段文本存储如何设计表结构&#xff1f; 分表存储 分表后多段存储 3 大段文本查找时如何建立索引&#xff1…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

C++ 设计模式 《小明的奶茶加料风波》

&#x1f468;‍&#x1f393; 模式名称&#xff1a;装饰器模式&#xff08;Decorator Pattern&#xff09; &#x1f466; 小明最近上线了校园奶茶配送功能&#xff0c;业务火爆&#xff0c;大家都在加料&#xff1a; 有的同学要加波霸 &#x1f7e4;&#xff0c;有的要加椰果…...

若依项目部署--传统架构--未完待续

若依项目介绍 项目源码获取 #Git工具下载 dnf -y install git #若依项目获取 git clone https://gitee.com/y_project/RuoYi-Vue.git项目背景 随着企业信息化需求的增加&#xff0c;传统开发模式存在效率低&#xff0c;重复劳动多等问题。若依项目通过整合主流技术框架&…...