文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

答了Mybatis这个问题后,面试官叫我回去等通知……

2024-12-03 15:35

关注

背景

前段时间在我的技术群里,大家讨论起了为什么UserMapper.java是个接口,没有具体实现类,而我们可以直接调用其方法?

关于这个问题,我之前面试过一些人,很多人是这么回答的:

我领导叫我们使用Mybatis,大家都这么用就这么用了(没想过,反正就这么用)。

虽然我不知道具体是怎么实现的,但我觉得肯定是……(此处略去若干的漫天猜想),但是也不对啊,难道是……(再次略去若干似懂非懂)。

使用动态代理实现的(然后就没有下文了)。

对于上面的三种回答,前面两种我们就没必要往下聊了。

但是第三种回答,就有必要往下问:那你说说动态代理有哪些实现方式?Mybatis使用的是哪一种?

如果这个问题你还能回答上来,那么还会继续问:UserMapper.java中大方法能不能重载?

如果你能回答上面的问题,本文就没必要往下看了,已经不适合你了。

问题分析

先来看一张图,这图里的代码就是我们前面写的demo:

为什么一个接口就能和一个xml文件给绑定的呢?这就是今天我们要聊的话题。

可能很多小伙伴不熟悉ibatis,2010年之前,还没有Mybatis,之后ibatis便成了现在的Mybatis,如果有兴趣的朋友,可以看到Mybatis中的包目录。

这个包目录中就还是ibatis,并且ibatis的作者现在就在腾讯上班,开发英雄联盟LOL。

如果有腾讯的小伙伴可以打听打听哈,大佬就在身边。言归正传。

Mapper层在Mybatis中现在是接口形式就搞定了,而在ibatis时代还是必须要有实现类的,我记得2012年的时候,使用的就是ibatis,Dao(Mapper)必须要有实现类。

下面我们就来看看Mybatis中是怎么做的。

使用案例

继续使用我们上一节中的代码。

controller

service实现类中

打一个断点,然后使用debug模式启动项目。并访问:

http://localhost:9002/test

  1. userMapper=org.apache.ibatis.binding.MapperProxy@6da21078 

发现Mybatis给UserMapper.java生成了一个代理对象,并且从名字上可以看出是JDK动态代理。

关于动态代理请,这里我推荐我之前写过的一篇文章:

https://gitbook.cn/m/mazi/activity/5d44e35e4fbf44126135c292?sut=c93c00a03b4f11eba07ad99b4dfbdab0&utm_source=chatweixinshare

其实,又差不多回到了ibatis时代,只是Mybatis中是通过动态代理的方式生成的代理类不是我们开发的,而是通过JDK动态代理生成的代理类。

下面我们也使用JDK动态代理来模拟一把。

  1. public class MapperProxy implements InvocationHandler { 
  2.     @SuppressWarnings("unchecked"
  3.     public  T newInstance(Class clz) { 
  4.         return (T) Proxy.newProxyInstance(clz.getClassLoader(), new Class[] { clz }, this); 
  5.     } 
  6.  
  7.     @Override 
  8.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
  9.         if (Object.class.equals(method.getDeclaringClass())) { 
  10.             try { 
  11.                 // 诸如hashCode()、toString()、equals()等方法,将target指向当前对象this 
  12.                 return method.invoke(this, args); 
  13.             } catch (Throwable t) { 
  14.             } 
  15.         } 
  16.         // 投鞭断流 
  17.         return new User((Integer) args[0], "田维常", 22); 
  18.     } 

再写一个测试类

  1. import com.tian.mybatis.entity.User
  2. import com.tian.mybatis.mapper.UserMapper; 
  3.  
  4. public class TestProxy { 
  5.     public static void main(String[] args) { 
  6.         MapperProxy proxy = new MapperProxy(); 
  7.  
  8.         UserMapper mapper = proxy.newInstance(UserMapper.class); 
  9.         User user = mapper.selectById(999); 
  10.  
  11.         System.out.println(user); 
  12.  
  13.         System.out.println(mapper.toString()); 
  14.     } 

输出

  1. User{id=999, userName='田维常', age=22, gender=null
  2. com.tian.mybatis.proxy.MapperProxy@39a054a5 

这便是Mybatis自动映射器Mapper的底层实现原理。

但是在Mybatis中,远远不是这么简单的,但是本质就是这样的。

下面我们就来大致分析一下Mybatis中的这个流程。

接口Mapper内的方法能重载吗?

类似下面:

public User getUserById(Integer id);

public User getUserById(Integer id, String name);

答案:不能

因为Mybatis中是使用package+Mapper+method全限名作为key,去xml内寻找唯一sql来执行的。

类似:key=com.tian.mybatis.UserMapper.getUserById,那么,重载方法时将导致矛盾。

对于Mapper接口,Mybatis禁止方法重载(overLoad) 。

在MapperMethod类的静态内部类中SqlCommand中有个resolveMappedStatement方法。

在Configuration中有个属性,就是项目启动的时候,会把Mapper.xml中信息解析到这个属性里,以我们指定的namespace+method作为key放到Map里面,后面我们调用Mapper接口动态类的某个方法时候再去map获取。

  1. protected final Map mappedStatements  

就是使用类的全路径名.方法作为key存放到Map中的。

总结

常用动态代理方式:JDK动态代理和CGlib动态代理。

Mybatis是采用JDK动态代理+反射+xml来解决接口绑定的,为我们创建可以调用的代理对象。

我们的Mapper中的方法是绝对不能重载的。

前端小智  本文转载自微信公众号「Java后端技术全栈」,可以通过以下二维码关注。转载本文请联系Java后端技术全栈公众号。

 

来源:Java后端技术全栈内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯