日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Mybatis接口Mapper内的方法为啥不能重载吗?

發布時間:2025/3/20 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mybatis接口Mapper内的方法为啥不能重载吗? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
點擊上方?好好學java?,選擇?星標?公眾號重磅資訊、干貨,第一時間送達 今日推薦:Nginx 為什么快到根本停不下來?個人原創100W+訪問量博客:點擊前往,查看更多作者:祖大俊來源:my.oschina.net/zudajun/blog/666223

動態代理的功能:通過攔截器方法回調,對目標target方法進行增強。

言外之意就是為了增強目標target方法。上面這句話沒錯,但也不要認為它就是真理,殊不知,動態代理還有投鞭斷流的霸權,連目標target都不要的科幻模式。

注:本文默認認為,讀者對動態代理的原理是理解的,如果不明白target的含義,難以看懂本篇文章,建議先理解動態代理。

1. 自定義JDK動態代理之投鞭斷流實現自動映射器Mapper

首先定義一個pojo。

public?class?User?{private?Integer?id;private?String?name;private?int?age;public?User(Integer?id,?String?name,?int?age)?{this.id?=?id;this.name?=?name;this.age?=?age;}//?getter?setter }

再定義一個接口UserMapper.java。

public?interface?UserMapper?{public?User?getUserById(Integer?id);?? }

接下來我們看看如何使用動態代理之投鞭斷流,實現實例化接口并調用接口方法返回數據的。

自定義一個InvocationHandler。

import?java.lang.reflect.InvocationHandler; import?java.lang.reflect.Method; import?java.lang.reflect.Proxy;public?class?MapperProxy?implements?InvocationHandler?{@SuppressWarnings("unchecked")public?<T>?T?newInstance(Class<T>?clz)?{return?(T)?Proxy.newProxyInstance(clz.getClassLoader(),?new?Class[]?{?clz?},?this);}@Overridepublic?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{if?(Object.class.equals(method.getDeclaringClass()))?{try?{//?諸如hashCode()、toString()、equals()等方法,將target指向當前對象thisreturn?method.invoke(this,?args);}?catch?(Throwable?t)?{}}//?投鞭斷流return?new?User((Integer)?args[0],?"zhangsan",?18);} }

上面代碼中的target,在執行Object.java內的方法時,target被指向了this,target已經變成了傀儡、象征、占位符。在投鞭斷流式的攔截時,已經沒有了target。

寫一個測試代碼:

public?static?void?main(String[]?args)?{MapperProxy?proxy?=?new?MapperProxy();UserMapper?mapper?=?proxy.newInstance(UserMapper.class);User?user?=?mapper.getUserById(1001);System.out.println("ID:"?+?user.getId());System.out.println("Name:"?+?user.getName());System.out.println("Age:"?+?user.getAge());System.out.println(mapper.toString()); }

output:

ID:1001 Name:zhangsan Age:18 x.y.MapperProxy@6bc7c054

這便是Mybatis自動映射器Mapper的底層實現原理。

可能有讀者不禁要問:你怎么把代碼寫的像初學者寫的一樣?沒有結構,且缺乏美感。

必須聲明,作為一名經驗老道的高手,能把程序寫的像初學者寫的一樣,那必定是高手中的高手。這樣可以讓初學者感覺到親切,舒服,符合自己的Style,讓他們或她們,感覺到大牛寫的代碼也不過如此,自己甚至寫的比這些大牛寫的還要好,從此自信滿滿,熱情高漲,認為與大牛之間的差距,僅剩下三分鐘。

2. Mybatis自動映射器Mapper的源碼分析

首先編寫一個測試類:

public?static?void?main(String[]?args)?{SqlSession?sqlSession?=?MybatisSqlSessionFactory.openSession();try?{StudentMapper?studentMapper?=?sqlSession.getMapper(StudentMapper.class);List<Student>?students?=?studentMapper.findAllStudents();for?(Student?student?:?students)?{System.out.println(student);}}?finally?{sqlSession.close();}}

Mapper長這個樣子:

public?interface?StudentMapper?{List<Student>?findAllStudents();Student?findStudentById(Integer?id);void?insertStudent(Student?student); }

org.apache.ibatis.binding.MapperProxy.java部分源碼。

public?class?MapperProxy<T>?implements?InvocationHandler,?Serializable?{private?static?final?long?serialVersionUID?=?-6424540398559729838L;private?final?SqlSession?sqlSession;private?final?Class<T>?mapperInterface;private?final?Map<Method,?MapperMethod>?methodCache;public?MapperProxy(SqlSession?sqlSession,?Class<T>?mapperInterface,?Map<Method,?MapperMethod>?methodCache)?{this.sqlSession?=?sqlSession;this.mapperInterface?=?mapperInterface;this.methodCache?=?methodCache;}@Overridepublic?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{if?(Object.class.equals(method.getDeclaringClass()))?{try?{return?method.invoke(this,?args);}?catch?(Throwable?t)?{throw?ExceptionUtil.unwrapThrowable(t);}}//?投鞭斷流final?MapperMethod?mapperMethod?=?cachedMapperMethod(method);return?mapperMethod.execute(sqlSession,?args);}//?...

org.apache.ibatis.binding.MapperProxyFactory.java部分源碼。

public?class?MapperProxyFactory<T>?{private?final?Class<T>?mapperInterface;@SuppressWarnings("unchecked")protected?T?newInstance(MapperProxy<T>?mapperProxy)?{return?(T)?Proxy.newProxyInstance(mapperInterface.getClassLoader(),?new?Class[]?{?mapperInterface?},?mapperProxy);}

這便是Mybatis使用動態代理之投鞭斷流。

3. 接口Mapper內的方法能重載(overLoad)嗎?(重要)

類似下面:

public?User?getUserById(Integer?id); public?User?getUserById(Integer?id,?String?name);

Answer:不能。

原因:在投鞭斷流時,Mybatis使用package+Mapper+method全限名作為key,去xml內尋找唯一sql來執行的。類似:key=x.y.UserMapper.getUserById,那么,重載方法時將導致矛盾。對于Mapper接口,Mybatis禁止方法重載(overLoad)。

最后,再附上我歷時三個月總結的?Java 面試 + Java 后端技術學習指南,筆者這幾年及春招的總結,github 1.4k star,拿去不謝!下載方式1.?首先掃描下方二維碼 2.?后臺回復「Java面試」即可獲取

總結

以上是生活随笔為你收集整理的Mybatis接口Mapper内的方法为啥不能重载吗?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。