【简写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;…

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

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

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…

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;使…

《汇编语言》- 读书笔记 - 实验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 …

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

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

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…

阿里云服务器租用价格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. 训练计划…

MATLAB导出图程序

本文将以代码的形式快速介绍MATLAB导出图到Paper 1 从simulation导出数 2 与simulation同源文件夹下创建导图m文件 代码如下&#xff1a; % 实验后的数据处理用 M-文件 % clear all % 清空工作空间 % close all      % 关闭所有图形窗口 % load adp.mat …

算法中关于数学的题目练习

算法中关于数学的题目练习 1、买不到的数目题目信息思路题解 2、蚂蚁感冒题目信息思路题解 3、饮料换购题目信息思路题解 1、买不到的数目 题目信息 思路 数学结论&#xff08;证明略&#xff09;&#xff1a; p、q为正整数且互质&#xff0c;不能由p、q凑出来的最大的数为(p…

java生态环境评价Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java 生态环境评价管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysq…

RK3399平台开发系列讲解(USB篇)USB控制传输方式介绍

🚀返回专栏总目录 文章目录 一、控制传输详解二、Setup阶段和Data阶段三、Setup 事务格式沉淀、分享、成长,让自己和他人都能有所收获!😄 📢USB控制传输是USB通信中的一种基本传输类型,用于控制USB设备的配置和操作。它由 Setup 阶段和 Data 阶段组成,可用于发送命令…

SIFT 2D/3D检测原理

一、SIFT 2D 二、SIFT 3D SIFT 3D关键点检测以及SAC-IA粗配准-CSDN博客

轻资产上班族副业,steam搬砖项目新手1周出结果

作为一个80后社畜&#xff0c;我打从上大学就喜欢倒腾各种赚钱的事情&#xff0c;不管操作网络上还是现实中的任何项目我都会亲自去摸索其中的赚钱原理&#xff0c;实践才能出真知。steam搬砖项目是我实操了3年多的项目&#xff0c;这个steam搬砖项目长期稳定又老牌阳光&#x…

深入理解lambda表达式

深入理解ASP.NET Core中的中间件和Lambda表达式 var builder WebApplication.CreateBuilder(args); var app builder.Build(); app.Use(async (context, next) > { // Add code before request. await next(context);// Add code after request.}); 这段C#代码是用于设…

模型 IPO(输入、处理、输出)学习模型

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_总纲目录。重在提升认知。信息转化与传递。 1 模型 IPO(输入、处理、输出)学习模型的应用 1.1 项目管理知识体系 PMBOK 中的IPO应用 在项目管理领域&#xff0c;PMBOK&#xff08;Project Management Body of Know…