不学无数——Mybatis自动映射器Mapper原理分析
发布日期:2021-08-22 06:43:24
浏览次数:3
分类:技术文章
本文共 3077 字,大约阅读时间需要 10 分钟。
在使用MyBatis
时,有时候会想,为什么只写一个接口没有编写任何的实现类,但是就能返回接口的实例,并且调用接口的方法返回数据库中的数据?此时脑海中浮现了写动态代理时候的记忆,记得动态代理也是接管了接口,不需要实际的代理角色。然后经过源码的Debug发现果然是运用了动态代理的技术。如果对于动态代理技术不熟悉的同学可以看
Mybatis自动映射器Mapper的源码分析
首先我们想Debug源码就得写一个测试类如下:
@Autowiredprivate SqlSessionFactory sqlSessionFactory;@Testpublic void testMybatis(){ SqlSession sqlSession = sqlSessionFactory.openSession(); TBapCheckPtsTranscdMapper mapper = sqlSession.getMapper(TBapCheckPtsTranscdMapper.class); TAmsAcPmtDtlPo tAmsAcPmtDtlPo= new TAmsAcPmtDtlPo(); mapper.queryTransCdByType(tAmsAcPmtDtlPo);}
Mapper
是这样的
public interface TBapCheckPtsTranscdMapper { List
首先先弄明白如何得到的接口的实际对象,由此Debug进去。
TBapCheckPtsTranscdMapper mapper = sqlSession.getMapper(TBapCheckPtsTranscdMapper.class);
然后进行Debug源码,发现在MapperProxyFactory
中,返回了代理对象。
protected T newInstance(MapperProxymapperProxy) { return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy); }
然后发现在执行接口的方法的时候进入到了代理MapperProxy
@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {try { //诸如hashCode()、toString()、equals()等方法,将target指向当前对象this if (Object.class.equals(method.getDeclaringClass())) { return method.invoke(this, args); } else if (isDefaultMethod(method)) { return invokeDefaultMethod(proxy, method, args); }} catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t);}final MapperMethod mapperMethod = cachedMapperMethod(method);return mapperMethod.execute(sqlSession, args);}
自己写一个小例子
首先自己定义个实体类
public class User { private Integer id; private String name; private String age; -----get,set方法}
然后Mapper接口如下
public interface UserMapper { public User findUserById(Integer id);}
代理类如下
public class MapperProxy implements InvocationHandler { @SuppressWarnings("unchecked") publicT newInstance(Class clz) { return (T) Proxy.newProxyInstance(clz.getClassLoader(), new Class[] { clz }, this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (Object.class.equals(method.getDeclaringClass())) { try { // 诸如hashCode()、toString()、equals()等方法,将target指向当前对象this return method.invoke(this, args); } catch (Throwable t) { } } //后面的xml解析之类的就先不模拟,在这直接返回数据 return new User((Integer) args[0], "zhangsan", "18"); }}
测试如下
public static void main(String[] args) { ClassLoader classLoader = UserMapper.class.getClassLoader(); MapperProxy mapperProxy = new MapperProxy(); //通过代理生成接口的实例对象 UserMapper mapper = (UserMapper) Proxy.newProxyInstance(classLoader, new Class[]{UserMapper.class},mapperProxy); User user = mapper.findUserById(10000); System.out.println("ID:" + user.getId()); System.out.println("Name:" + user.getName()); System.out.println("Age:" + user.getAge());}
打印如下
ID:10000Name:zhangsanAge:18Practice.Day09.MapperProxy@24d46ca6
转载地址:https://blog.csdn.net/weixin_33738555/article/details/89628005 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2024年03月28日 18时12分46秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Emacs-103-使用spacemacs自带配置显示行号
2019-04-27
021_Excel的条件格式
2019-04-27
022_Excel空白值批量填充默认值
2019-04-27
023_emacs git-gutter+报错解决
2019-04-27
024_spacemacs支持org-pomodoro的声音提示
2019-04-27
025_everything搜索使用体验
2019-04-27
026_好用的windows小工具clover
2019-04-27
027-Mac触摸板实现窗口移动
2019-04-27
028_AUTOSAR RTE学习笔记-1
2019-04-27
029_AUTOSAR VFB学习笔记-2
2019-04-27
030_AUTOSAR软件组件学习笔记
2019-04-27
031_AUTOSAR学习笔记_BSW
2019-04-27
032_AUTOSAR学习笔记_接口
2019-04-27
033_PowerShell学习初探
2019-04-27
034_PowerShell中的HOME环境变量
2019-04-27
模拟登陆C#实现
2019-04-27
【Task05】LeetCode腾讯精选打卡
2019-04-27
掌握JS压缩图片,这一篇就够了
2019-04-27
2020大厂web前端面试都喜欢问这些
2019-04-27
云计算的可信新边界:边缘计算与协同未来
2019-04-27