【简写MyBatis】01-简单映射器

前言

新开一个坑,为了学习一下MyBatis的源码,写代码是次要的,主要为了吸收一下其中的思想和手法。

目的

关联对象接口和映射类的问题,把 DAO 接口使用代理类,包装映射操作。

知识点

  1. 动态代理
  2. 简单工厂模式
  3. InvocationHandler接口的使用

实现

既然是简易的MyBatis编写,那肯定得看下源码了;先来一波回忆,MyBatis的使用:

忘记的朋友可以看下之前写的MyBatis手册: https://blog.csdn.net/weixin_43908900/article/details/129780085

https://www.cnblogs.com/xbhog/p/17258782.html

@Test
public void testMybatis(){//加载核心配置文件try {//字符流加载配置InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");//创建sql连接工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);//创建session连接,设置true,默认提交事务SqlSession sqlSession = sqlSessionFactory.openSession(true);//反射获取类对象UserMapper mapper = sqlSession.getMapper(UserMapper.class);List<User> userAll = mapper.getUserAll();System.out.println(userAll);} catch (IOException e) {e.printStackTrace();}
}

代码中可以看到,接口和映射器有关系的地方应该是sqlSession.getMapper(UserMapper.class);点进去。

先看映射器工厂类:MapperProxyFactory

这部分就是我们本次实现的地方。

public class MapperProxyFactory<T> {private final Class<T> mapperInterface;private final Map<Method, MapperMethodInvoker> methodCache = new ConcurrentHashMap<>();public MapperProxyFactory(Class<T> mapperInterface) {this.mapperInterface = mapperInterface;}public Class<T> getMapperInterface() {return mapperInterface;}public Map<Method, MapperMethodInvoker> getMethodCache() {return methodCache;}@SuppressWarnings("unchecked")protected T newInstance(MapperProxy<T> mapperProxy) {return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);}public T newInstance(SqlSession sqlSession) {final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);return newInstance(mapperProxy);}}

简易映射器类图:

MapperProxy代理类来代理需要使用的接口,为了方便后续的维护扩展,在代理类上加一层代理工厂类MapperProxyFactory

使用代理类的好处是: 动态代理允许 MyBatis 在不修改接口实现的情况下,为接口方法提供自定义的行为。这意味着开发者只需要定义接口和 SQL 映射,而无需编写接口的实现类。这种设计促进了关注点分离,使得数据访问逻辑(SQL)与业务逻辑更加清晰,MapperProxy 能够在运行时将 SQL 语句与接口方法动态绑定,这样,MyBatis 可以根据接口方法的签名和注解或 XML 配置来执行相应的 SQL 操作。

使用简单工厂模式的好处: 实现代码复用和模块化,对代理逻辑和接口使用解耦,灵活性高,不改变公共接口等。

总之都是为了项目的高度灵活、扩展、复用等。

通过上述的分析,现在进行代码编写的流程比较明朗了。

代理类的实现:

public class MapperProxy<T> implements InvocationHandler, Serializable {private static final long serialVersionUID = -6424540398559729838L;//模拟SqlSessionprivate Map<String, String> sqlSession;private final Class<T> mapperInterface;public MapperProxy(Map<String, String> sqlSession, Class<T> mapperInterface) {this.sqlSession = sqlSession;this.mapperInterface = mapperInterface;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//检查一个方法是否来自特定的类或者是一系列接口中的一个//是Object自身的方法,就没必要代理,直接调用就行if (Object.class.equals(method.getDeclaringClass())) {return method.invoke(this, args);} else {//需要匹配的是类名+方法名return "你的被代理了!" + sqlSession.get(mapperInterface.getName() + "." + method.getName());}}}

映射器代理工厂实现:

public class MapperProxyFactory<T> {private final Class<T> mapperInterface;public MapperProxyFactory(Class<T> mapperInterface) {this.mapperInterface = mapperInterface;}public T newInstance(Map<String, String> sqlSession) {final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface);return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, mapperProxy);}}

执行流程如下:

测试

public void testApp() {MapperProxyFactory<IUserDao> proxyFactory = new MapperProxyFactory<>(IUserDao.class);Map<String,String> sqlSession = new HashMap<>();sqlSession.put("com.xbhog.IUserDao.getUserName","模拟执行 Mapper.xml 中 SQL 语句的操作:查询用户姓名");IUserDao userDao = proxyFactory.newInstance(sqlSession);String userName = userDao.getUserName("100001");System.out.println(userName);
}

总结

  1. 通过追溯MyBatis中的源码,明确本文的主要的内容
  2. 明确目标类的依赖关系
  3. 代码实现简易效果
  4. 明确执行流程
  5. 测试代码,符合预期结果

参考&学习

https://mp.weixin.qq.com/s/G3fZES2FvNQK8JLnd9Hx9w

AI大模型辅助

MyBatis源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/686779.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HMI界面:感官与体验俱佳的智能家居界面分享

Hello&#xff0c;我是大千UI工场&#xff0c;本期分享HMI人机交互界面在智能家居领域的案例&#xff0c;关注大千&#xff0c;学习N多UI干货&#xff0c;有设计需求&#xff0c;可以联络。 设计感官和体验俱佳智能家居的UI界面时&#xff0c;可以考虑以下几个方面&#xff1a;…

防火墙HA详解

防火墙HA&#xff08;High Availability&#xff09;是指在防火墙系统中使用冗余设备或技术来提高其可用性和可靠性的方法。 防火墙HA的实现方式通常包括以下几个步骤&#xff1a; 1. 设备冗余&#xff1a;使用两台或多台防火墙设备&#xff0c;通过HA技术将它们连接在一起&a…

Slider滑动输入条(antd-design组件库)简单使用

1.Slider滑动输入条 滑动型输入器&#xff0c;展示当前值和可选范围。 2.何时使用 当用户需要在数值区间/自定义区间内进行选择时&#xff0c;可为连续或离散值。 组件代码来自&#xff1a; 滑动输入条 Slider - Ant Design 3.本地验证前的准备 参考文章【react项目antd组件-de…

c入门番外篇——我们用密码交流怎么样?

最近看到一个关于华罗庚先生的小故事。一九二九年&#xff0c;苏家驹先生在上海《学艺》七卷上发表了《代数式的五次方程之解法》&#xff0c;华罗庚先生发现此文在一个十二阶段的行列式中有计算差错&#xff0c;便写出《苏家驹之代数解法不能成立的理由》的论文&#xff0c;于…

OpenCV-40 绘制直方图

一、使用matplotlib画直方图 可以利用matplotlib把OpenCV统计得到的直方图绘制出来 示例代码如下&#xff1a; import cv2 import matplotlib.pyplot as pltlena cv2.imread("beautiful women.png") # 变为黑白图片 gray cv2.cvtColor(lena, cv2.COLOR_BGR2GRAY…

什么是索引

在数据库中&#xff0c;索引&#xff08;Index&#xff09;是一种数据结构&#xff0c;用于快速查找和访问数据库表中的特定数据行。索引可以理解为数据库表的目录&#xff0c;它存储了指向实际数据的引用&#xff0c;从而加快了数据库查询的速度。 索引通常是根据数据库表中的…

XUbuntu22.04之apt与snap如何重装软件(二百一十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

SpringBoot实现OneDrive文件上传

SpringBoot实现OneDrive文件上传 源码 OneDriveUpload: SpringBoot实现OneDrive文件上传 获取accessToken步骤 参考文档&#xff1a;针对 OneDrive API 的 Microsoft 帐户授权 - OneDrive dev center | Microsoft Learn 1.访问Azure创建应用Microsoft Azure&#xff0c;使…

MQL5语言键盘快捷键交易代码实现

文章目录 一、输入变量与全局变量二、初始化函数设置三、事件函数设置 一、输入变量与全局变量 //--- input parameters input double InpLots 0.1; /* Lots */ // Requested volume input int InpMagic 1024; /* Magic…

JAVA学习-集合.使用Properties

Properties是Java集合框架中的一种特殊的Map实现类&#xff0c;它用于处理键值对的配置文件。下面是Properties的特点和使用方法的概述&#xff0c;以及附上示例代码和说明。 一、特点&#xff1a; 1. Properties继承自Hashtable类&#xff0c;因此它是基于哈希表实现的。 2. …

《汇编语言》- 读书笔记 - 实验9 根据材料编程

《汇编语言》- 读书笔记 - 实验9 根据材料编程 需求所需的相关知识属性字节每一位的含义 分析字符位置属性 解答思路代码 效果 需求 在屏幕中间分别显示 绿色、绿底红色、白底蓝色 的字符串 welcome to masm!。 所需的相关知识 80x25 彩色字符模式显示缓冲区(以下简称为显示…

关于DVWA靶场Could not connect to the database service的几种解决办法

总的来说这个问题都是 config 配置文件没有修改正确 一般修改数据库的用户名和密码与 phpstudy 一致并且添加了 key 就能初始化成功的 但是我还遇到过另一种情况&#xff0c;修改了上面的东西依旧无法连接到数据库 Could not connect to the database service. Please check …

什么是NAT网关?联通云NAT网关有什么优势

在当今云计算时代&#xff0c;网络安全和连接性是企业发展的关键因素之一。NAT网关&#xff08;Network Address Translation Gateway&#xff09;是一种网络设备&#xff0c;它可以在私有网络和公共网络之间进行地址转换&#xff0c;从而使得内部网络中的设备能够与外部网络进…

如果马斯克投资OpenAI,而不是收购推特会如何?

从去年年底开始&#xff0c;AIGC就开始快速流行&#xff0c;生成式人工智能技术的不断演变&#xff0c;以OpenAI受到微软的追投开始&#xff0c;再以ChatGPT的发布快速在互联网市场蔓延为标志性事件&#xff0c;进而开始引领了一场新兴人工智能的快速发展之路。 去年&#xff…

DPDK系列之四十一数据收发整体流程源码分析之二流程框架

一、基本说明 本篇接着分析流程的源码&#xff0c;在收发数据前的基础准备。包括端口的初始化、配置等&#xff0c;当一切基础的准备完成后&#xff0c;工作状态也已经就绪&#xff0c;则可以开始工作了。端口的处理是启动程序前的一个开始环节。 在这个示例中&#xff0c;主要…

Javaweb之SpringBootWeb案例之AOP通知类型的详细解析

3.1 通知类型 在入门程序当中&#xff0c;我们已经使用了一种功能最为强大的通知类型&#xff1a;Around环绕通知。 Around("execution(* com.itheima.service.*.*(..))") public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {//记录方法执行开始…

第13讲我创建的投票列表实现

新建我创建的投票页面 {"path": "pages/createVoteList/createVoteList","style": {"navigationBarTitleText": "我创建的投票"}}个人中心页面&#xff0c;加下 点击 “我创建的投票”跳转列表页面 goVoteList:function(){u…

ROS目标跟随(路径规划、slam、定位、雷达)——接上文,改善跟随的位置

确保进行跟随的小车始终在身后 最终效果代码改进 最终效果 ROS目标跟随改进版 代码改进 这里给出上一篇博客的链接&#xff1a;https://blog.csdn.net/m0_71523511/article/details/135610191 使用上一篇的launch文件创建机器人时&#xff0c;ros会自动创建一个坐标系相对关系…

阿里云服务器租用价格2024年新版活动报价和租用收费标准

2024年最新阿里云服务器租用费用优惠价格表&#xff0c;轻量2核2G3M带宽轻量服务器一年61元&#xff0c;折合5元1个月&#xff0c;新老用户同享99元一年服务器&#xff0c;2核4G5M服务器ECS优惠价199元一年&#xff0c;2核4G4M轻量服务器165元一年&#xff0c;2核4G服务器30元3…

《剑指Offer》笔记题解思路技巧优化 Java版本——新版leetcode_Part_3

《剑指Offer》笔记&题解&思路&技巧&优化_Part_3 &#x1f60d;&#x1f60d;&#x1f60d; 相知&#x1f64c;&#x1f64c;&#x1f64c; 相识&#x1f622;&#x1f622;&#x1f622; 开始刷题1. LCR 138. 有效数字——表示数值的字符串2. LCR 139. 训练计划…