MyBatis之Mapper动态代理开发
MyBatis之Mapper動態代理開發
2017/9/301.SqlSession的使用范圍
1.SqlSessionFactoryBuilder
SqlSessionFactoryBuilder是以工具類的方式來使用:需要創建sqlSessionFactory時就new一個 SqlSessionFactoryBuilder
2.sqlSessionFactory
正常開發時,以單例方式管理sqlSessionFactory,整個系統運行過程中sqlSessionFactory只有一個實例,將來和Spring整合后由Spring以單例方式管理sqlSessionFactory
3.SqlSession
SqlSession是一個面向用戶(程序員)的接口,程序員調用 SqlSession接口的方法進行操作數據庫。那么我們會思考:SqlSession能否以單例方式使用???由于 SqlSession是線程不安全的,所以 SqlSession最佳應用范圍在方法體內。也就是說在方法體內定義局部變量 SqlSession的對象來使用。
2.MyBatis開發DAO的方式
我們先來看看MyBatis原始開發dao的開發方式,發現原始開發的問題,然后再來看看MyBatis使用mapper動態代理開發dao的方式(也是MyBatis目前使用的開發dao的方式)。
2.1原始dao的開發方式
程序員需要編寫dao接口:
和dao接口的實現類:
然后就能在測試類中使用。測試類代碼如下:
我們來看看這種方式開發有什么問題?
- 1.dao的實現類中存在重復代碼,整個mybatis操作的過程代碼模板重復(都是先創建sqlSession、調用sqlSession的方法、關閉sqlSession)。
- 2.dao的實現類中存在硬編碼,調用sqlSession方法時將statement的id硬編碼。
下面我們看看mapper動態代理的方式。
2.2mapper動態代理的方式
這種方式下程序員只需要寫dao接口,dao接口實現對象由mybatis自動生成代理對象。因為本身dao在三層架構中就是一個通用的接口。
2.2.1mapper開發規范
要想讓mybatis自動創建dao接口實現類的代理對象,必須要遵循一些規則:
- 1.mapper.xml中 namespace指定為mapper接口的全限定名。此步驟的目的:將mapper.xml和mapper.java關聯。
- 2.mapper.xml中statement的id就是mapper.java中的方法名。
- 3.mapper.xml中statement的parameterType和mapper.java中方法輸入參數一致。
- 4.mapper.xml中statement的resultType和mapper.java中方法的返回值類型一致。
采用這種方式后,我們便可將第一篇文章中提到的User.xml改為UserMapper.xml。文件目錄如下:
其中有些類我們會在后面用到。
2.2.2mapper.xml(映射文件)
mapper映射文件的命名方式建議表名加Mapper.xml,namespace指定為mapper接口的全限定名。
2.2.3mapper.java接口
mybatis提出了mapper接口,相當于dao接口,mapper接口的命名方式建議為表名加Mapper.
2.3.4將mapper.xml在SqlMapConfing.xml中進行注冊
2.3.5mapper接口返回單個對象和集合對象
在UserMapper.java中添加如下兩個方法:
對于UserMapper.xml,不管查詢記錄是單條還是多條,在statement(即UserMapper.xml)中的resultType都定義一致,都是單條記錄映射的pojo類型。
而對于UserMapper.java接口方法中的返回值,如果返回的是單個對象,返回值類型是pojo,生成的代理對象內部會自動通過selectOne獲取記錄,如果返回值類型是多條對象,生成的代理對象內部會自動通過selectList獲取記錄。
測試代碼如下:
使用Mapper代理方式進行開發,使程序員只需要關注UserMapper.java接口中的方法,它的實現類由Mapper自動為我們生成,帶來了很大的方便。但這種方式也有它的弊端。
2.3.6mapper代理開發的問題
- 1.返回值的問題:如果方法(即UserMapper.java接口中的方法)調用的statement中返回是多條記錄,而mapper.java方法的返回值為pojo,此時代理對象通過selectOne調用,但由于返回的是多條記錄所以會報錯:Expected one result (for null ) to be returned by selectOne() but found 4;
- 2.輸入參數的問題:使用mapper代理的方式開發,mapper接口方法的輸入參數只有一個,可擴展性是否很差?答:可擴展性沒有問題,因為dao層就是通用的,可以通過擴展pojo(定義pojo包裝類型,后面第四篇文章–MyBatis輸入輸出映射會講擴展pojo的知識)來將不同的參數(可以是pojo也可以是簡單類型)傳入進去。
總結
以上是生活随笔為你收集整理的MyBatis之Mapper动态代理开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux shell编程学习总结
- 下一篇: 定义一个结构体指针需要分配存储空间?