Mybatis中sqlSession.getMapper背后的原理
在通过MyBatis操作数据库之前我们一定先通过Session对象获取指定Mappper接口的代理对象。如下代码所示:
public class UserMapper{@Select(value="SELECT * FROM user")public List<User> findAll();
}
public static void main(String [] args){Configuration configuration = new Configuration();configuration.addMapper(UserMapper.class);SqlSessionFactory sqlSessionFactory = new DefaultSqlSessionFactory(configuration);// 获取SqlSession对象try(SqlSession sqlSession = sqlSessionFactory.openSession();){UserMapper userMapper = sqlSession.getMapper(UserMapper.class);List<User> userList = userMapper.findAll();}catch(Exception e){//TODO 异常信息}
}
调用链
1.DefaultSqlSession.调用getMapper方法 -> 2.Configuration.调用getMapper方法 -> 3.MapperRegistry调用getMapper方法|||-------------------------------------------------------------------------------------||||-->4.判断knownMappers缓存是否已经解析过指定的Mapper接口,没解析过抛错(在调用addMapper方法时就将接口添加到缓存中并对接口中的方法进行解析).解析过创建代理对象public <T> T getMapper(Class<T> type, SqlSession sqlSession) {final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);if (Objects.isNull(mapperProxyFactory)){throw new BindingException("Type " + type + " is not known to the MapperRegistry.");}try {return mapperProxyFactory.newInstance(sqlSession);} catch (Exception e) {throw new BindingException("Error getting mapper instance. Cause: " + e, e);}}|||--> 5.创建代理对象,MapperProxy实现了InvocationHandler接口,使用JDK动态代理创建public T newInstance(SqlSession sqlSession) {final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);return newInstance(mapperProxy);}protected T newInstance(MapperProxy<T> mapperProxy) {// 用JDK自带的动态代理生成映射器return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, mapperProxy);}
注意第5代逻辑:
// 已解析过的Mapper接口及对应的代理工厂缓存private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<Class<?>, MapperProxyFactory<?>>();public <T> T getMapper(Class<T> type, SqlSession sqlSession) {final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);if (Objects.isNull(mapperProxyFactory)) {throw new BindingException("Type " + type + " is not known to the MapperRegistry.");}try {return mapperProxyFactory.newInstance(sqlSession);} catch (Exception e) {throw new BindingException("Error getting mapper instance. Cause: " + e, e);}}
先从缓存中获取接口对应的代理工厂,并判断是否存储代理工厂。不存在时抛错,表示此接口没有注册过无法创建代理对象.
何时向缓存中添加接口及对应的代理工厂呢?如下代码:
public <T> void addMapper(Class<T> type) {// mapper必须是接口!才会添加if (type.isInterface()) {if ( knownMappers.containsKey((type)) {// 如果重复添加了,报错throw new BindingException("Type " + type + " is already known to the MapperRegistry.");}boolean loadCompleted = false;try {// 将mapper接口放入缓存并为其创建独立的mapper接口代理对象工厂// 每个Mapper接口有一个独立的代理工厂knownMappers.put(type, new MapperProxyFactory<T>(type));// 在运行分析器之前添加类型非常重要// 否则,绑定可能会由// 映射器解析器。如果类型已知,则不会尝试。MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);// 解析mapper接口及相应的mapper.xml文件parser.parse();loadCompleted = true;} finally {// 如果加载过程中出现异常需要再将这个mapper从mybatis中删除,这种方式比较丑陋吧,难道是不得已而为之?if (!loadCompleted) {knownMappers.remove(type);}}}
}
在注册Mapper 接口时,会向缓存中添加接口对应的代理工厂,以便后面通过接口获取代理对象调用方法。
相关文章:
Mybatis中sqlSession.getMapper背后的原理
在通过MyBatis操作数据库之前我们一定先通过Session对象获取指定Mappper接口的代理对象。如下代码所示: public class UserMapper{Select(value"SELECT * FROM user")public List<User> findAll(); }public static void main(String [] args){Conf…...
[环境配置]conda 64位安装32位python
进入32模式 set CONDA_FORCE_32BIT1创建环境 conda create --name yourEnv python3.8退出32模式 set CONDA_FORCE_32BIT0ok...
某虚假交友APP(信息窃取)逆向分析
应用初探 在群里水群的时候 群u发了一个交友APP 于是拿来分析一下 可以看到应用打开后又一个登录的界面 需要用户输入手机号与验证码进行登录 #在线云沙箱分析 将APK放入某安信云沙箱中分析 提示应用请求了过多的敏感权限 逆向分析 直接拖入Jadx分析 好在程序没有加固 也没…...
基于FPGA的按键消抖
按键工作原理 当KEY1按下时,整条电路就会导通,这个时候KEY1就是低电平; 当KEY1松开时,整条电路就会断开,这个时候KEY1就是高定平; 我们可以通过判断KEY1的高低电平来判断按键是否被按下。 为什么按键消…...
1.网络编程-网络协议
目录 网络编程是什么 网络编程三要素 OSI七层网络模型 TCP/IP五层模型 SSL/TLS 是哪层协议 网络编程是什么 网络编程是计算机科学中的一个重要领域,它涉及到编写能够在网络环境中进行通信的程序。网络编程的核心目标是使不同的设备能够通过网络交换信息&#…...
代码+视频,手动绘制logistic回归预测模型校准曲线(Calibration curve)(2)
校准曲线图表示的是预测值和实际值的差距,作为预测模型的重要部分,目前很多函数能绘制校准曲线。 一般分为两种,一种是通过Hosmer-Lemeshow检验,把P值分为10等分,求出每等分的预测值和实际值的差距 另外一种是calibrat…...
金融数据_Scikit-Learn决策树(DecisionTreeClassifier)实例
金融数据_Scikit-Learn决策树(DecisionTreeClassifier)实例 逻辑回归: 逻辑回归常被用于二分类问题, 比如涨跌预测。你可以将涨跌标记为类别, 然后使用逻辑回归进行训练。 决策树和随机森林: 决策树和随机森林是用于分类问题的强大模型。它们能够处理非线性关系, 并且对于特征…...
bash的login shell与non-login shell,以及各自的初始化过程
识别login shell与non-login shell login shell 可能是以-开头的 [almalinuxVM-AlmaLinux8-tmpl-wanlinwang ~]$ echo $0 -bash # "-" is the first character. Therefore, this is a login shell.或者以--login启动的bash [almalinuxVM-AlmaLinux8-tmpl-wanlinw…...
为什么苹果 Mac 电脑需要使用清理软件?
尽管 Apple Mac 电脑因其卓越的性能、简洁高效的 macOS 操作系统及独特的美学设计备受全球用户青睐,但任何电子设备在长期使用后都难以避免面临系统资源日渐累积的问题。其中一个重要维护需求在于,随着使用时间的增长,Mac电脑可能会由于系统垃…...
33. UE5 RPG使用增强输入激活GameplayAbility(三)
在前面的文章,我们实现了使用GameplayTag和InputAction的对应绑定的数据,并且添加到了增强输入映射的上下文中,实现了通过按键打印对应的GameplayTag,这只是我们基础需要制作的。目的主要是为了实现在GameplayAblity上面设置对应的…...
speech to text 库FastASR交叉编译arm target的配置
FastASR是一个比较方便的SPEECH TO TEXT的AI库。开源。下面介绍下其在交叉编译到ARM target时候的交叉编译的cmake配置: cmake_minimum_required(VERSION 3.10)project(FastASR)SET(CMAKE_C_COMPILER "/home/xxx/buildroot/output/platform_name/host/bin/aar…...
WPS快速将插入Excle数据插入Word
前置条件: 一张有标题、数据的excle表格word中的表格与excle表格标题对应或包含电脑已经安装WPS软件 第一步、根据word模板设计excle模板,标头对应 第二步、word上面选【引用】--【邮件】,选打开数据源,找到excle文件,…...
Springboot 集成Rabbitmq之延时队列
1.首先确保已经引入了Spring AMQP和RabbitMQ的相关依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </dependency> 2. 创建一个普通队列并设置TTL&#x…...
【云开发笔记NO.22】运用云原生产品打造技术中台
一、云原生产品与技术中台的结合点 云原生产品以其容器化、微服务化、自动化等特性,为技术中台的建设提供了强大的技术支持。容器化技术使得应用可以更容易地进行部署和管理,提高了应用的可移植性和弹性。微服务架构则让应用更加模块化,便于…...
C++进阶(五) 哈希
1. unordered系列关联式容器 1.1 unordered_map 1.2 unordered_map的接口说明 2. 底层结构 2.1 哈希概念 2.2 哈希冲突 2.3 哈希函数 2.4 哈希冲突解决 2.4.1 闭散列 2.4.2 开散列 3. 模拟实现 3.1 unordered_set 3.2 unordered_map 4.哈希的应用 4.1 位图 4.1.…...
【算法基础】基于异或的排序、基于异或的经典面试题
文章目录 1. 传统交换2. 异或与异或的规律3. 基于异或的排序4. 需要注意的地方5. 经典面试题15.1 题目5.2 思路5.3 实现 6. 经典面试题26.1 题目6.2 思路6.3 实现 1. 传统交换 传统交换方法如下: def swap(i, j):tmp ii jj tmp通过开辟一个额外的变量空间&…...
HTML2:列表和表格
列表 有序列表 ordered list ol 无序列表 unordered list ul 定义列表 definition list dl 1,有序列表 每条列表前自带一个序号 2,无序列表 每条列表前自带一个小圆点 3,定义列表 注意:dl中放的不是li列表而是dt列表和dd表项 dt代表术语标题 dd代表术语内容 一个…...
用于无人机小型化设计的高精度温补晶振
用于无人机小型化设计的高精度温补晶振:TG2016SMN和TG2520SMN。无人机的发展可以说是非常的迅速,在安防,农业,交通,电力,直播等领域经常能看到无人机大显身手。无人机的应用场最是非常的广泛,功能更强&…...
轨迹规划 | 图解最优控制LQR算法(附ROS C++/Python/Matlab仿真)
目录 0 专栏介绍1 最优控制理论2 线性二次型问题3 LQR的价值迭代推导4 基于差速模型的LQR控制5 仿真实现5.1 ROS C实现5.2 Python实现5.3 Matlab实现 0 专栏介绍 🔥附C/Python/Matlab全套代码🔥课程设计、毕业设计、创新竞赛必备!详细介绍全…...
工业视觉检测
目录 我对工业视觉检测的了解 一、关键组成部分 二、应用场景 三、技术挑战 我对工业视觉检测的了解 工业视觉检测是利用机器视觉技术对产品质量进行自动化检查的过程,它在制造业中扮演着至关重要的角色,用于确保产品质量、提高生产效率、减少人工成…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...
Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...
