Mybatis【11】-- Mybatis Mapper动态代理怎么写?
1.回顾Mybatis执行sql的流程
在之前的代码中我们的运行过程再梳理一下,首先我们执行Test,调用dao接口方法

接口的定义:

调用接口的实现类方法:

最后才是调用真正的sql:

上面的代码是在接口实现类里面自己去执行id,查找并执行mapper文件里面的sql,那么我们想是不是可以减少一步呢?
如果我们不用自己实现接口,只需要将接口的名字和mapper文件的namespace对应起来,将接口里面的方法名与sql语句标签的id对应起来是不是就可以了呢?
事实上,mybatis提供了这样的做法,这就是mapper动态代理。
2.mapper动态代理怎么写?
首先主配置文件(Mybatis.xml),在里面配置数据库连接信息,注册需要扫描的mapper文件:

定义数据库查询的接口,里面每一个接口的名字很重要,需要和mapper里面每一条sql对应起来:

定义mapper文件(namespace是接口的全限定类名):

那我们在使用的时候,需要使用sqlSession.getMapper()方法,里面传入的是接口,意思是通过接口的全限定名,也就是前面在mapper.xml文件里面配置的命名空间nameSpace,这样一来,就是获取到了代理类,将dao和mapper.xml文件关联起来了,而每条sql的id与我们的接口方法名字对应起来)

我们在前面还写到过一个selectStudentMap()方法,但是里面调用的是和SelectList()一样的sql,在接口的实现类里面我们自己处理了一下,但是现在使用自动实现的话,底层只会调用SelectOne()或者SelectList()方法,所以这个方法会报错,如果接受类型是list,那么框架会自动使用selectList()方法,否则就会选择selectOne()这个方法。
在这里我们使用的是返回的是map,所以自动选择返回selectOne()方法,那么就会报错。如果我们需要使用自动返回map的话,可以自己定一个map,或者返回list之后再处理,这个知识点后面再介绍,有兴趣可以访问:mybatis的mapper返回map结果集
3.mapper动态代理怎么做的?
打一个断点在sqlSession.getMapper()方法上:

我们可以看到执行下面的接口方法(接口SqlSession的方法)
<T> T getMapper(Class<T> var1);
这是一个接口,我们可以看到实现接口的有两个类,一个是DefaultSqlSession,一个是SqlSessionManager,我们需要看的是DefaultSqlSession下面的接口:
public <T> T getMapper(Class<T> type) {
return this.configuration.getMapper(type, this);
}
我们知道,在创建sqlsession的时候,confiiguration这个配置对象已经创建完成。跟进去,这是使用mapper注册器对象的getMapper()方法,将当前的sqlSession对象传递进去:
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return mapperRegistry.getMapper(type, sqlSession);
}
我们跟进去源码,可以发现里面使用knownMappers.get(type)来获取mapper代理工厂,这个konwnMappers是一个hashMap,这个hashMap里面已经初始化了mapperProxyFactory对象了,获取到工厂对象之后,再去使用sqlSession实例化:
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
if (mapperProxyFactory == null) {
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);
}
}
实例化的时候,使用了mapper动态代理:
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
从下面的debug结果中我们可以看到,这是动态代理的结果,我们看到的是dao,但是动态代理对这个dao做了增强,实则是一个mapperProxy。

【作者简介】:
秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使缓慢,驰而不息。这个世界希望一切都很快,更快,但是我希望自己能走好每一步,写好每一篇文章,期待和你们一起交流。
此文章仅代表自己(本菜鸟)学习积累记录,或者学习笔记,如有侵权,请联系作者核实删除。人无完人,文章也一样,文笔稚嫩,在下不才,勿喷,如果有错误之处,还望指出,感激不尽~

Mybatis【11】-- Mybatis Mapper动态代理怎么写?的更多相关文章
- MyBatis开发Dao层的两种方式(Mapper动态代理方式)
MyBatis开发原始Dao层请阅读我的上一篇博客:MyBatis开发Dao层的两种方式(原始Dao层开发) 接上一篇博客继续介绍MyBatis开发Dao层的第二种方式:Mapper动态代理方式 Ma ...
- 02.MyBatis在DAO层开发使用的Mapper动态代理方式
在实际开发中,Mybatis作用于DAO层,那么Service层该如何调用Mybatis Mybatis鼓励使用Mapper动态代理的方式 Mapper接口开发方法只需要程序员编写Mapper接口(相 ...
- Mybatis之旅第二篇-Mapper动态代理方式
一.引言 通过上一篇mybatis的入门学习,我们已经会使用mybatis实现简单的增删改查,但是我们也发现了用原始Dao开发的一些问题: Dao方法体存在重复代码:通过SqlSessionFacto ...
- Mybatis框架三:DAO层开发、Mapper动态代理开发
这里是最基本的搭建:http://www.cnblogs.com/xuyiqing/p/8600888.html 接下来做到了简单的增删改查:http://www.cnblogs.com/xuyiqi ...
- mybatis由浅入深day01_5.3 Mapper动态代理方法
5.3 Mapper动态代理方法(程序员只需要写mapper接口(相当于dao接口)) 5.3.1 实现原理(mapper代理开发规范) 程序员还需要编写mapper.xml映射文件 程序员编写map ...
- MyBatis使用Mapper动态代理开发Dao层
开发规范 Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同原始Dao接口实现类方法. Mappe ...
- JavaWeb_(Mybatis框架)Mapper动态代理开发_三
系列博文: JavaWeb_(Mybatis框架)JDBC操作数据库和Mybatis框架操作数据库区别_一 传送门 JavaWeb_(Mybatis框架)使用Mybatis对表进行增.删.改.查操作_ ...
- Mybatis入门——基础方式的增删该查、mapper动态代理方式的CRUD、类型转换器
一.基础方式的增删该查: 1.mybatis约定:输入参数parameterType和输出参数resulrType在形式上只能有一个. 2.如果输入/输出参数:是简单类型(8个基本类型加String) ...
- Mybatis(五)Spring整合Mybatis之mapper动态代理开发
要操作的数据库: IDEA创建的Java工程,目录结构如下: 一.导包 1.spring的jar包 2.Mybatis的jar包 3.Spring+mybatis的整合包. 4.Mysql的数据库驱动 ...
- Mybatis框架基础入门(三)--Mapper动态代理方式开发
使用MyBatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper动态代理开发方法. 原始Dao开发方法需要程序员编写Dao接口和Dao实现类,此方式开发Dao,存在以下问题: Dao方 ...
随机推荐
- 全网最适合入门的面向对象编程教程:46 Python函数方法与接口-函数与事件驱动框架
全网最适合入门的面向对象编程教程:46 Python 函数方法与接口-函数与事件驱动框架 摘要: 函数是 Python 中的一等公民,是一种可重用的代码块,用于封装特定的逻辑:事件驱动框架是一种编程模 ...
- QT数据可视化框架编程实战之三维柱状图从入门到精通_补天云QT技术培训专家
QT数据可视化框架编程实战之三维柱状图从入门到精通_补天云QT技术培训专家 简介 本文将介绍QT数据可视化框架(QT DataVisualization 模块)编程实战之三维柱状图(Q3DBars)的 ...
- .NEET跨平台绘图基础库--SkiaSharp
SkiaSharp 是一个跨平台的 2D 图形 API,用于 .NET 平台,基于 Google 的 Skia 图形库.它提供了全面的 2D API,可以在移动.服务器和桌面模型上渲染图像.SkiaS ...
- IP地址集中管控:从分配规划、现网管理到合规性监测、准入控制全周期监管
当前,网络已成为企业必不可少的资源,企业网络系统也在不断扩展,IP地址数量不断增长,随之而来的是IP地址管理问题凸显.如何高效集中地管理网络中的IP地址,IP如何有效划分,成为影响企业网络可用性和质量 ...
- Java如何将Object转换成指定Class对象
在Java中,将Object转换为指定类型的Class对象实际上是两个不同概念的操作: 将Object实例转换为特定类型的实例:这通常涉及到类型转换(如(MyType) myObject)或者通过反射 ...
- 1. java + react 实现 HRM
1. 云服务的三种方式 1.1 IAAS 基础设施即服务 ,只会提供基础的设施,eg:服务器,网络等 : 1.2 PAAS 平台即服务 ,提供平台,可以把自己写好的代码部署到平台上 : 1.3 SAA ...
- Linux中ln 链接命令的用法
ln的语法 Usage: ln [OPTION]... [-T] TARGET LINK_NAME (1st form) or: ln [OPTION]... TARGET (2nd form) or ...
- 云原生周刊:开发人员使用 GPT-4 的 30 种重要方法 | 2023-6-5
OpenAI 最新的大型语言模型 GPT-4 有非常多的用途,那么,作为开发人员,应该如何去使用它,来帮助自己工作呢? 在最近的 Hacker News 问答中,很多开发人员参与了讨论和分享. 也有人 ...
- Cloth Simulation with Root Finding and Optimization
目录 0 前言 1 Implicit Method 1.1 Root-finding 1.2 Optimization 1.3 Insight 2 Newton-Raphson Method 3 Ma ...
- Multi-Patch Prediction Adapting LLMs for Time Series Representation Learning
这篇论文是出自2024ICML的一篇论文,作者成功将大语言模型应用到时序模型之中,并在时序领域取得了很好的效果,不仅如此,作者还设置了多种下游任务,从论文结果得知,作者的模型在下游任务处都取得了很好的 ...