MyBatis你只写了接口为啥就能执行SQL啊?
一、静态代理
又是一年秋招季,很多小伙伴开始去大城市打拼。来大城市第一件事就是租房,免不了和中介打交道,因为很多房东很忙,你根本找不到他。从这个场景中就可以抽象出来代理模式:
ISubject:被访问者资源的抽象
SubjectImpl:被访问者具体实现类(房东)
SubjectProxy:被访问者的代理实现类(中介)
UML图如下:

举个例子来理解一下这个设计模式:
老板让记录一下用户服务的响应时间,用代理模式来实现这个功能。



一切看起来都非常的美好,老板又发话了,把产品服务的响应时间也记录一下吧。又得写如下3个类:
IProductService
ProductServiceImpl
ProductServiceProxy
UserServiceProxy和ProductServiceProxy这两个代理类的逻辑都差不多,却还得写2次。其实这个还好,如果老板说,把现有系统的几十个服务的响应时间都记录一下吧,你是不是要疯了?这得写多少代理类啊?
二、动态代理
黑暗总是暂时的,终究会迎来黎明,在JDK1.3之后引入了一种称之为动态代理(Dynamic Proxy)的机制。使用该机制,我们可以为指定的接口在系统运行期间动态地生成代理对象,从而帮助我们走出最初使用静态代理实现AOP的窘境
动态代理的实现主要由一个类和一个接口组成,即java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。
让我们用动态代理来改造一下上面记录系统响应时间的功能。虽然要为IUserService和IProductService两种服务提供代理对象,但因为代理对象中要添加的横切逻辑是一样的。所以我们只需要实现一个InvocationHandler就可以了。代码如下

UML图如下。恭喜你,你现在已经理解了Spring AOP是怎么回事了,就是这么简单,今天先不展开谈Spring

先简单谈谈动态代理在Mybatis中是如何被大佬玩的出神入化的
三、Mybatis核心设计思路
相信用过mybatis的小伙伴都能理解下面这段代码,通过roleMapper这个接口直接从数据库中拿到一个对象
Role role = roleMapper.getRole(3L);
直觉告诉我,一个接口是不能运行的啊,一定有接口的实现类,可是这个实现类我自己没写啊,难道mybatis帮我们生成了?你猜的没错,mybatis利用动态代理帮我们生成了接口的实现类,这个类就是:
org.apache.ibatis.binding.MapperProxy,
我先画一下UML图,MapperProxy就是下图中的SubjectProxy类

和上面的UML类图对比一下,发现不就少了一个SubjectImpl类吗?那应该就是SubjectProxy类把SubjectImple类要做的事情做了呗,猜对了。SubjectProxy通过SubjectImple和SubjectImple.xml之间的映射关系知道自己应该执行什么SQL。所以mybatis最核心的思路就是这么个意思,细节之类的可以看源码,理清最主要的思路,看源码就能把握住重点。
关于源码相关的内容,更进一步的解释动态代理在MyBatis中的使用,可以参考以前的一篇文章:《动态代理之投鞭断流!看一下MyBatis的底层实现原理!》
附录:
https://mp.weixin.qq.com/s/ToMvAD0-QyUJgg_1eFvcaA
MyBatis你只写了接口为啥就能执行SQL啊?的更多相关文章
- 如何优雅的将Mybatis日志中的Preparing与Parameters转换为可执行SQL
原文链接 疫情期间大家宅在家里是不是已经快憋出“病”了~~ 公司给开了VPN,手机电脑都能连,手机装上APP测试包,就能干活了,所以walking从2020.02.01入京以来,已经窝在家里11天 ...
- 补偿接口中循环一直执行sql的问题
事件: 项目即将上线,测试,观察日志,发现一sql在dal.xml中一直刷日志,但对应在biz日志却是空的 排查步骤: 1.查看对应日志的sql,在项目中找到对应代码所在位置,查看入口与代码逻辑 接口 ...
- [MyBatis]DAO层只写接口,不用写实现类
团队开发一个项目,由老大架了一个框架,遇到了DAO层不用写接口了,我也是用了2次才记住这个事的,因为自己一直都是习惯于写DAO层的实现类,所以,习惯性的还是写了个实现类.于是遇到错误了. 找不到那个方 ...
- 当使用cokie进行数据交互时候,cookie只需存储该对象的id即可不需要存放其他数据;只需在写个接口根据cookie里面的对象id来创建对象
当使用cokie进行数据交互时候,cookie只需存储该对象的id即可不需要存放其他数据:只需在写个接口根据cookie里面的对象id来创建对象
- drf序列化高级、自定义只读只写、序列化覆盖字段、二次封装Response、数据库查询优化(断关联)、十大接口、视图家族
目录 自定义只读 自定义只写 序列化覆盖字段 二次封装Response 数据库关系分析 断外键关联关系 ORM操作外键关系 ORM四种关联关系 基表 系列化类其他配置(了解) 十大接口 BaseSer ...
- MyBatis 源码分析——SqlSession接口和Executor类
mybatis框架在操作数据的时候,离不开SqlSession接口实例类的作用.可以说SqlSession接口实例是开发过程中打交道最多的一个类.即是DefaultSqlSession类.如果笔者记得 ...
- Mybatis的dao层实现 接口代理方式实现规范+plugins-PageHelper
Mybatis的dao层实现 接口代理方式实现规范 Mapper接口实现时的相关规范: Mapper接口开发只需要程序员编写Mapper接口而不用具体实现其代码(相当于我们写的Imp实现类) Mapp ...
- Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring
Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring 非原创[只为记录],原博文地址:https://www.cnblogs.com/ ...
- 基于Mybatis实现一个查库的接口
基本功能就是写一个接口,该接口的主要功能是根据给的条件查询特定表: 先通过Workbench来看一下在给定条件下的查询的结果,先给出最终的结果查询的表以及查询的条件: 也就是该接口实现在image_t ...
随机推荐
- 如何解决div背景色半透明,里面的图片不透明问题
用rgba可以实现,不能用opacity 背景做成透明的背景图,opacity属性影响子集的,除非把两者独立开~
- CentOS - Eclipse安装Shelled
一,下载Shelled: https://sourceforge.net/projects/shelled/ 二,打开Eclipse,以离线方式安装: Help->Install New Sof ...
- 深入理解JVM-java虚拟机栈
1.java虚拟机栈 1. Java虚拟机栈也是线程私有的,它的生命周期与线程相同(随线程而生,随线程而灭) 2. 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowErro ...
- 【RAC】rac环境下的数据库备份与还原
[RAC]rac环境下的数据库备份与还原 一.1 BLOG文档结构图 一.2 前言部分 一.2.1 导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~ ...
- Python 多线程爬取站酷(zcool.com.cn)图片
极速爬取下载站酷(https://www.zcool.com.cn/)设计师/用户上传的全部照片/插画等图片. 项目地址:https://github.com/lonsty/scraper 特点: 极 ...
- 肖哥HCNP-学前准备篇笔记
HCNA:助理 HCNP:工程师 HCIE:专家 vmvare workstation 1.安装 2.创建新的虚拟机-->典型-->稍后安装系统-->选择系统模式-->选择位置 ...
- pycharm新建项目后按钮灰色问题
同样适用于导入别人的新项目后无法运行问题 原因一: pycharm没有设置系统解析器 解决方法一: 打开pycharm->File->Settings->Project Interp ...
- 大数据JavaWeb之java基础巩固----Junit&反射&注解
最近打算从0开始学学大数据,目前的主业是Android开发,但是当年毕业之后其实是搞J2EE的,所以打算没事又来拓展一下后台的技能,扩宽一下自己的知识体系对于自己的未来也能够多一些可能,另外大数据的一 ...
- 当电脑上有两个mysql时,如何让jmeter连接自己需要的那个mysql
1.当有两个mysql时,修改其中一个的mysql端口号为3307 ,也可以是其他8788, 在文件my.ini中修改端口号为:3307:修改完之后记得重启mysql哦:dos下命令可以用net st ...
- java怎么比较两个实体类的属性值
分享一下比较两个实体类的工具包 package cn.mollie.utils; import java.beans.Introspector; import java.beans.PropertyD ...