title: MyBatis之Mapper動態(tài)代理開發(fā)
tags: MyBatis
categories: MyBatis
若圖片無法顯示簸呈,請前往我的博客查看,相應(yīng)文章鏈接:http://codingxiaxw.cn/2016/11/07/33-MyBatis%E4%BD%BF%E7%94%A8mapper%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E5%BC%80%E5%8F%91/
1.SqlSession的使用范圍
1.SqlSessionFactoryBuilder
SqlSessionFactoryBuilder是以工具類的方式來使用:需要創(chuàng)建sqlSessionFactory時就new一個 SqlSessionFactoryBuilder
2.sqlSessionFactory
正常開發(fā)時伤极,以單例方式管理sqlSessionFactory蛹找,整個系統(tǒng)運(yùn)行過程中sqlSessionFactory只有一個實例,將來和Spring整合后由Spring以單例方式管理sqlSessionFactory
3.SqlSession
SqlSession是一個面向用戶(程序員)的接口哨坪,程序員調(diào)用 SqlSession接口的方法進(jìn)行操作數(shù)據(jù)庫庸疾。那么我們會思考:SqlSession能否以單例方式使用?当编?届慈?由于 SqlSession是線程不安全的,所以 SqlSession最佳應(yīng)用范圍在方法體內(nèi)。也就是說在方法體內(nèi)定義局部變量 SqlSession的對象來使用金顿。
2.MyBatis開發(fā)DAO的方式
我們先來看看MyBatis原始開發(fā)dao的開發(fā)方式词渤,發(fā)現(xiàn)原始開發(fā)的問題,然后再來看看MyBatis使用mapper動態(tài)代理開發(fā)dao的方式(也是MyBatis目前使用的開發(fā)dao的方式)串绩。
2.1原始dao的開發(fā)方式
程序員需要編寫dao接口:[圖片上傳失敗...(image-186922-1526286026566)]和dao接口的實現(xiàn)類:[圖片上傳失敗...(image-e73fbe-1526286026566)]
然后就能在測試類中使用缺虐。測試類代碼如下:
[圖片上傳失敗...(image-4eef03-1526286026566)]
我們來看看這種方式開發(fā)有什么問題?
- 1.dao的實現(xiàn)類中存在重復(fù)代碼,整個mybatis操作的過程代碼模板重復(fù)(都是先創(chuàng)建sqlSession礁凡、調(diào)用sqlSession的方法高氮、關(guān)閉sqlSession)。
- 2.dao的實現(xiàn)類中存在硬編碼顷牌,調(diào)用sqlSession方法時將statement的id硬編碼剪芍。
下面我們看看mapper動態(tài)代理的方式。
2.2mapper動態(tài)代理的方式
這種方式下程序員只需要寫dao接口窟蓝,dao接口實現(xiàn)對象由mybatis自動生成代理對象罪裹。因為本身dao在三層架構(gòu)中就是一個通用的接口。
2.2.1mapper開發(fā)規(guī)范
要想讓mybatis自動創(chuàng)建dao接口實現(xiàn)類的代理對象运挫,必須要遵循一些規(guī)則:
- 1.mapper.xml中 namespace指定為mapper接口的全限定名状共。此步驟的目的:將mapper.xml和mapper.java關(guān)聯(lián)。
- 2.mapper.xml中statement的id就是mapper.java中的方法名谁帕。
- 3.mapper.xml中statement的parameterType和mapper.java中方法輸入?yún)?shù)一致峡继。
- 4.mapper.xml中statement的resultType和mapper.java中方法的返回值類型一致。
其中有些類我們會在后面用到。
2.2.2mapper.xml(映射文件)
mapper映射文件的命名方式建議表名加Mapper.xml,namespace指定為mapper接口的全限定名儡循。
2.2.3mapper.java接口
mybatis提出了mapper接口,相當(dāng)于dao接口,mapper接口的命名方式建議為表名加Mapper.
public interface UserMapper{};
2.3.4將mapper.xml在SqlMapConfing.xml中進(jìn)行注冊
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
2.3.5mapper接口返回單個對象和集合對象
在UserMapper.java中添加如下兩個方法:
對于UserMapper.xml舶吗,不管查詢記錄是單條還是多條,在statement(即UserMapper.xml)中的resultType都定義一致择膝,都是單條記錄映射的pojo類型誓琼。
而對于UserMapper.java接口方法中的返回值,如果返回的是單個對象调榄,返回值類型是pojo踊赠,生成的代理對象內(nèi)部會自動通過selectOne獲取記錄,如果返回值類型是多條對象每庆,生成的代理對象內(nèi)部會自動通過selectList獲取記錄。
測試代碼如下:使用Mapper代理方式進(jìn)行開發(fā)今穿,使程序員只需要關(guān)注UserMapper.java接口中的方法缤灵,它的實現(xiàn)類由Mapper自動為我們生成,帶來了很大的方便。但這種方式也有它的弊端腮出。
2.3.6mapper代理開發(fā)的問題
- 1.返回值的問題:如果方法(即UserMapper.java接口中的方法)調(diào)用的statement中返回是多條記錄帖鸦,而mapper.java方法的返回值為pojo,此時代理對象通過selectOne調(diào)用胚嘲,但由于返回的是多條記錄所以會報錯:
Expected one result (for null ) to be returned by selectOne() but found 4
; - 2.輸入?yún)?shù)的問題:使用mapper代理的方式開發(fā)作儿,mapper接口方法的輸入?yún)?shù)只有一個,可擴(kuò)展性是否很差?答:可擴(kuò)展性沒有問題馋劈,因為dao層就是通用的攻锰,可以通過擴(kuò)展pojo(定義pojo包裝類型,后面第四篇文章--MyBatis輸入輸出映射會講擴(kuò)展pojo的知識)來將不同的參數(shù)(可以是pojo也可以是簡單類型)傳入進(jìn)去妓雾。
2018.3.19更
歡迎加入我的Java交流1群:659957958娶吞。群里目前已有1800人,每天都非承狄觯活躍妒蛇,但為了篩選掉那些不懷好意的朋友進(jìn)來搞破壞,所以目前入群方式已改成了付費(fèi)方式楷拳,你只需要支付9塊錢绣夺,即可獲取到群文件中的所有干貨以及群里面各位前輩們的疑惑解答;為了鼓勵良好風(fēng)氣的發(fā)展欢揖,讓每個新人提出的問題都得到解決乐导,所以我將得到的入群收費(fèi)收入都以紅包的形式發(fā)放到那些主動給新手們解決疑惑的朋友手中。在這里浸颓,我們除了談技術(shù)物臂,還談生活、談理想产上;在這里棵磷,我們?yōu)槟愕膶W(xué)習(xí)方向指明方向,為你以后的求職道路提供指路明燈晋涣;在這里仪媒,我們把所有好用的干貨都與你分享。還在等什么谢鹊,快加入我們吧算吩!
2018.4.21更:如果群1已滿或者無法加入,請加Java學(xué)習(xí)交流2群:305335626 佃扼。群2作為群1的附屬群偎巢,除了日常的技術(shù)交流、資料分享兼耀、學(xué)習(xí)方向指明外压昼,還會在每年互聯(lián)網(wǎng)的秋春招時節(jié)在群內(nèi)發(fā)布大量的互聯(lián)網(wǎng)內(nèi)推方式求冷,話不多說,快上車吧窍霞!
3.聯(lián)系
If you have some questions after you see this article,you can tell your doubts in the comments area or you can find some info by clicking these links.