本篇內(nèi)容介紹了“如何解決Mybatis導(dǎo)致的問(wèn)題”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)專(zhuān)注為客戶(hù)提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站建設(shè)、成都網(wǎng)站制作、應(yīng)城網(wǎng)絡(luò)推廣、小程序制作、應(yīng)城網(wǎng)絡(luò)營(yíng)銷(xiāo)、應(yīng)城企業(yè)策劃、應(yīng)城品牌公關(guān)、搜索引擎seo、人物專(zhuān)訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供應(yīng)城建站搭建服務(wù),24小時(shí)服務(wù)熱線:18980820575,官方網(wǎng)址:aaarwkj.com
創(chuàng)新互聯(lián)專(zhuān)業(yè)為企業(yè)提供紅山網(wǎng)站建設(shè)、紅山做網(wǎng)站、紅山網(wǎng)站設(shè)計(jì)、紅山網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、紅山企業(yè)網(wǎng)站模板建站服務(wù),十余年紅山做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
背景
前段時(shí)間在我的技術(shù)群里,大家討論起了為什么UserMapper.java是個(gè)接口,沒(méi)有具體實(shí)現(xiàn)類(lèi),而我們可以直接調(diào)用其方法?
關(guān)于這個(gè)問(wèn)題,我之前面試過(guò)一些人,很多人是這么回答的:
1.我領(lǐng)導(dǎo)叫我們使用Mybatis,大家都這么用就這么用了(沒(méi)想過(guò),反正就這么用)。
2.雖然我不知道具體是怎么實(shí)現(xiàn)的,但我覺(jué)得肯定是……(此處略去若干的漫天猜想),但是也不對(duì)啊,難道是……(再次略去若干似懂非懂)。
3.使用動(dòng)態(tài)代理實(shí)現(xiàn)的(然后就沒(méi)有下文了)。
對(duì)于上面的三種回答,前面兩種我們就沒(méi)必要往下聊了。
但是第三種回答,就有必要往下問(wèn):那你說(shuō)說(shuō)動(dòng)態(tài)代理有哪些實(shí)現(xiàn)方式?Mybatis使用的是哪一種?
如果這個(gè)問(wèn)題你還能回答上來(lái),那么還會(huì)繼續(xù)問(wèn):UserMapper.java中大方法能不能重載?
如果你能回答上面的問(wèn)題,本文就沒(méi)必要往下看了,已經(jīng)不適合你了。
問(wèn)題分析
先來(lái)看一張圖,這圖里的代碼就是我們前面寫(xiě)的demo:
為什么一個(gè)接口就能和一個(gè)xml文件給綁定的呢?這就是今天我們要聊的話題。
可能很多小伙伴不熟悉ibatis,2010年之前,還沒(méi)有Mybatis,之后ibatis便成了現(xiàn)在的Mybatis,如果有興趣的朋友,可以看到Mybatis中的包目錄。
這個(gè)包目錄中就還是ibatis,并且ibatis的作者現(xiàn)在就在騰訊上班,開(kāi)發(fā)英雄聯(lián)盟LOL。
如果有騰訊的小伙伴可以打聽(tīng)打聽(tīng)哈,大佬就在身邊。言歸正傳。
Mapper層在Mybatis中現(xiàn)在是接口形式就搞定了,而在ibatis時(shí)代還是必須要有實(shí)現(xiàn)類(lèi)的,我記得2012年的時(shí)候,使用的就是ibatis,Dao(Mapper)必須要有實(shí)現(xiàn)類(lèi)。
下面我們就來(lái)看看Mybatis中是怎么做的。
使用案例
繼續(xù)使用我們上一節(jié)中的代碼。
controller
service實(shí)現(xiàn)類(lèi)中
打一個(gè)斷點(diǎn),然后使用debug模式啟動(dòng)項(xiàng)目。并訪問(wèn):
http://localhost:9002/test
userMapper=org.apache.ibatis.binding.MapperProxy@6da21078
發(fā)現(xiàn)Mybatis給UserMapper.java生成了一個(gè)代理對(duì)象,并且從名字上可以看出是JDK動(dòng)態(tài)代理。
關(guān)于動(dòng)態(tài)代理請(qǐng),這里我推薦我之前寫(xiě)過(guò)的一篇文章:
https://gitbook.cn/m/mazi/activity/5d44e35e4fbf44126135c292?sut=c93c00a03b4f11eba07ad99b4dfbdab0&utm_source=chatweixinshare
其實(shí),又差不多回到了ibatis時(shí)代,只是Mybatis中是通過(guò)動(dòng)態(tài)代理的方式生成的代理類(lèi)不是我們開(kāi)發(fā)的,而是通過(guò)JDK動(dòng)態(tài)代理生成的代理類(lèi)。
下面我們也使用JDK動(dòng)態(tài)代理來(lái)模擬一把。
public class MapperProxy implements InvocationHandler { @SuppressWarnings("unchecked") public <T> T newInstance(Class<T> 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指向當(dāng)前對(duì)象this return method.invoke(this, args); } catch (Throwable t) { } } // 投鞭斷流 return new User((Integer) args[0], "田維常", 22); } }
再寫(xiě)一個(gè)測(cè)試類(lèi)
import com.tian.mybatis.entity.User; import com.tian.mybatis.mapper.UserMapper; public class TestProxy { public static void main(String[] args) { MapperProxy proxy = new MapperProxy(); UserMapper mapper = proxy.newInstance(UserMapper.class); User user = mapper.selectById(999); System.out.println(user); System.out.println(mapper.toString()); } }
輸出
User{id=999, userName='田維常', age=22, gender=null} com.tian.mybatis.proxy.MapperProxy@39a054a5
這便是Mybatis自動(dòng)映射器Mapper的底層實(shí)現(xiàn)原理。
但是在Mybatis中,遠(yuǎn)遠(yuǎn)不是這么簡(jiǎn)單的,但是本質(zhì)就是這樣的。
下面我們就來(lái)大致分析一下Mybatis中的這個(gè)流程。
接口Mapper內(nèi)的方法能重載嗎?
類(lèi)似下面:
public User getUserById(Integer id);
public User getUserById(Integer id, String name);
答案:不能
因?yàn)镸ybatis中是使用package+Mapper+method全限名作為key,去xml內(nèi)尋找唯一sql來(lái)執(zhí)行的。
類(lèi)似:key=com.tian.mybatis.UserMapper.getUserById,那么,重載方法時(shí)將導(dǎo)致矛盾。
對(duì)于Mapper接口,Mybatis禁止方法重載(overLoad) 。
在MapperMethod類(lèi)的靜態(tài)內(nèi)部類(lèi)中SqlCommand中有個(gè)resolveMappedStatement方法。
在Configuration中有個(gè)屬性,就是項(xiàng)目啟動(dòng)的時(shí)候,會(huì)把Mapper.xml中信息解析到這個(gè)屬性里,以我們指定的namespace+method作為key放到Map里面,后面我們調(diào)用Mapper接口動(dòng)態(tài)類(lèi)的某個(gè)方法時(shí)候再去map獲取。
protected final Map<String, MappedStatement> mappedStatements
就是使用類(lèi)的全路徑名.方法作為key存放到Map中的。
“如何解決Mybatis導(dǎo)致的問(wèn)題”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
網(wǎng)站欄目:如何解決Mybatis導(dǎo)致的問(wèn)題
當(dāng)前網(wǎng)址:http://aaarwkj.com/article40/igcpho.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、響應(yīng)式網(wǎng)站、網(wǎng)站收錄、面包屑導(dǎo)航、App設(shè)計(jì)、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)