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方 ...
随机推荐
- 补: Rest 风格请求处理的的内容补充(1)
补: Rest 风格请求处理的的内容补充(1) Rest风格请求:注意事项和细节 客户端是PostMan 可以直接发送Put,delete等方式请求,可不设置Filter 如果哟啊SpringBoot ...
- C# 调用WebService 笔记
最近开发工作涉及到一些关于webService调用的问题,因为太久没有做过这部分,踩了一点坑,做个笔记记录一下,避免下次踩坑. 说明 C#调用webService基本有两种方法,一种是静态调用,也就是 ...
- TFC-Pretraining: 基于时间频率一致性对时间序列进行自监督对比预训练《Self-Supervised Contrastive Pre-Training for Time Series via Time-Frequency Consistency》(时间序列、时序表征、时频一致性、对比学习、自监督学习)
2023年11月10日,今天看一篇论文,现在17:34,说实话,想摆烂休息,不想看,可还是要看,拴Q. 论文:Self-Supervised Contrastive Pre-Training for ...
- MDC – Checkbox
前言 Checkbox 不是搭配 TextField 使用, 而是搭配 FormField. 所以独立一篇来写. 参考 Docs – Selection controls: checkboxes 效果 ...
- Figma 学习笔记 – Keyboard Shortcut and Tips 小技巧
参考: 10 tips to work 10x faster in Figma 15 tips to design 15X faster in Figma | Figma Tutorial 2021 ...
- Vue——前端框架
Vue Vue 快速入门 <!DOCTYPE html> <html lang="en"> <head> <meta char ...
- Go 学习路线图
基础阶段 学习内容: 掌握 Go 的基本语法,包括变量.常量.数据类型(如整数.浮点数.字符串.布尔值.数组.切片.映射等).运算符等. 理解程序的控制流,如条件语句(if-else.switch-c ...
- IDEA如何查看每一行代码的提交记录(人员,时间)
前言 我们在使用IDEA开发时,一般需要使用git来管理我们的代码,而且大家协同开发. 有时候,我们在开发的时候,经常需要看一下当前的代码时谁开发的,除了看类上面的作者外,更精细的方式是看每一行代 ...
- LeetCode 730. Count Different Palindromic Subsequences (区间DP)
题意 给一个字符串S,求它所有子序列中不同非空回文串的数量.字符串由 'a' 'b' 'c' 'd' 四个字母组成. 由于题目要求的是不同回文串. abba 的回文串子序列为 a,b,aba,abba ...
- 高通dump ftrace & kernelshark使用
简介 高通 ramdump 可以解析出 ftrace,方便用于追踪 快省稳 问题. kernelshark 是一个可以查看 trace event 的图形化工具,方便梳理和观察内核微观行为. trac ...