Mybatis系列之介面式程式設計
引言
在前面的文章《Mybatis系列之簡單示例》曾有一段程式碼涉及到了介面式程式設計,當時並沒有展開闡述,今天我們單獨把這一段拿出來表一表。
在講Mybatis介面式程式設計之前,我們先回憶一下前面是如何呼叫對映檔案中的SQL程式碼的。通常情況下,都是使用SqlSession例項的selectXXX(selectOne, selectList, selectMap)方法來執行對映檔案中相應的SQL語句的,這些方法都有一個共同的特徵,那就是第一個引數都是String型別的,我們需要使用這個引數明確告之Mybatis我們是需要執行對映檔案的哪一個元素下的SQL語句,所以這個引數內容應該是對映檔案的名稱空間加上相應元素的id值,如:
- Object obj = session.selectOne("com.emerson.learning.mapping.user.getByID", 240);
- User user = (User)obj;
- ... ...
這條語句告訴我們,要在名稱空間com.emerson.learning.mapping.user下查詢一個id為getById的元素,並執行其SQL語句。在獲取返回值之後,我們還需要對其進行強型別轉換。
這裡存在一些潛在的問題:
- 為了確保名稱空間的唯一性,通常會使用相對較長的、且有一定含義的字串來作為其值,這樣就很難保證我們在程式碼不出現拼寫錯誤的情況,即使是直接從對映檔案拷貝過來的,也存在不經意間被修改的可能性;
- 從selectXXX方法的簽名可以看到,她的第二個引數是Object型別,那麼如果我們傳入的引數型別與對映檔案中由parameterType屬性指定的型別不一致時,將會出現不可預知的錯誤
- 同樣,selectXXX方法返回值使用了泛型,我們須確保用於接收其返回值的變數型別與對映檔案中屬性resultType指定的型別相一致
Mybatis規避上述風險的手段,我們稱之為介面式程式設計,也就是我們今天的主題。
定義代理介面
介面式程式設計,我們可以簡單的理解為Mybatis為對映檔案定義了一個代理介面,以後全部通過這個介面來和對映檔案互動,而不再是使用以前方法。
對映檔案如何知道自己被哪個介面代理呢?這裡就是通過名稱空間來實現的,對映檔案的名稱空間再也不是隨心所欲的定義的了,而是要使用代理介面的全限定名作為其名稱空間。所謂全限定名,就是介面所在的包名加上介面名稱。
- <mappernamespace="com.emerson.learning.dao.ICommunicatorDao">
- <selectid="getById"parameterType="int"resultType="Communicator">
- select * from communicator where communicator_id=#{id}
- </select>
- <selectid="getAll"resultType="Communicator">
- select * from communicator order by communicator_name
- </select>
- </mapper>
介面定義好了,那麼如何將對映檔案中的select / insert / update / delete 等元素與代理介面中的方法繫結呢?其實很簡單,只需要在代理介面中定義一些方法,並以相應元素的id屬性值做為方法名,parameterType屬性值做為方法引數型別,屬性resultType值做為方法的返回值即可。下面定義的兩個方法就分別對應上面對映檔案中的兩個select元素。
- publicinterface ICommunicatorDao {
- public Communicator getById(int id);
- public List<Communicator> getAll();
- }
有些朋友會問了,介面定義好了,是不是還要再定義一個實現類呢?答案是否定的。Mybatis會使用動態代理機制來幫助我們完成額外的工作,我們需要做的就是把這個介面註冊到Mybatis中。在Mybatis的總配置檔案中,加入如下語句。
- <mappers>
- <mapperclass="com.emerson.learning.dao.ICommunicatorDao"/>
- </mappers>
這樣,我們就可以在Java程式碼中直接呼叫我們定義的代理介面中的方法了。
- @Test
- publicvoid testGetById() {
- SqlSession session = sqlSessionFactory.openSession();
- try {
- ICommunicatorDao cp = session.getMapper(ICommunicatorDao.class);
- Communicator c = cp.getById(1);
- if (null == c) {
- System.out.println("the result is null.");
- } else {
- System.out.println(c);
- }
- } finally {
- session.close();
- }
- }
- @Test
- publicvoid testGetAll() {
- SqlSession session = sqlSessionFactory.openSession();
- try {
- ICommunicatorDao cp = session.getMapper(ICommunicatorDao.class);
- List<Communicator> list = cp.getAll();
- for (Communicator c : list) {
- System.out.println(c);
- }
- } finally {
- session.close();
- }
- }
是不是很簡單,而且程式碼看上去比之前的要簡潔了許多。
介面式程式設計與之前的呼叫方式相比較,有以下優點:
- 呼叫方法明確,因為我們呼叫的是介面中的某個具體方法,而不再是通過一個字串來指定執行對映檔案中的某個SQL語句了
- 傳入引數和返回值都不再是Object了,這樣就可以在程式碼編寫階段確保傳入的引數型別是正確的,也不再需要對返回值進行強型別轉換了
- 最主要的一點,就是將來Mybatis遇到了Spring,更能發揮出介面式程式設計的強大潛力。
使用註解
在Mybatis3.0之後,加入了更強的註解功能。如果不需要使用到較複雜的SQL語句,可以直接把對映檔案省去,直接在Java程式碼中使用註解的方式指定SQL語句。這種寫法很簡潔,但卻失去了對映檔案的靈活性。
- publicinterface ICommunicatorDao {
- @Select("SELECT * FROM communicator WHERE communicator_id=#{id}")
- public Communicator getById(@Param(value = "id") int id);
- @Select("SELECT * FROM communicator ORDER BY communicator_id")
- public List<Communicator> getAll();
- }
相關推薦
Mybatis系列之介面式程式設計
引言 在前面的文章《Mybatis系列之簡單示例》曾有一段程式碼涉及到了介面式程式設計,當時並沒有展開闡述,今天我們單獨把這一段拿出來表一表。 在講Mybatis介面式程式設計之前,我們先回憶一下前面是如何呼叫對映檔案中的SQL程式碼的。通常情況下,都是使用SqlSe
mybatis入門之介面式程式設計
上一節《mybatis入門之Helloworld》我們介紹了mybatis的入門搭建知識,但是上一節的程式設計方式現在不常用了,現在比較常用的是介面式程式設計,專案結構和程式碼請先按照上一節的來完成,
九、Mybatis之介面式程式設計的原理(大致流程介紹)
(一)Mybatis之介面式程式設計的原理(大致流程介紹) 1、載入配置資訊…… 2、通過載入配置資訊載入一個代理工廠Map(PS:這個Map存放的是介面Class與對應的代理工廠的對映) 3、通過介面的Class從代理工廠Map取出對應的代理工廠 4、
八、Mybatis之介面式程式設計
(一)介面式程式設計與非介面式程式設計的區別 1.namespace的命名方式: (1)非介面式程式設計:命名比較隨意 <mapper namespace="Command"> (2)介面式程式設計:必須是Mapper檔案對應介面的全限定
Mybatis系列(六)介面式程式設計
Mybatis系列之介面式程式設計引言在前面的文章《Mybatis系列之簡單示例》曾有一段程式碼涉及到了介面式程式設計,當時並沒有展開闡述,今天我們單獨把這一段拿出來表一表。在講Mybatis介面式程式設計之前,我們先回憶一下前面是如何呼叫對映檔案中的SQL程式碼的。通常情況
MyBatis學習筆記(二)- 介面式程式設計
MyBatis 的 HelloWorld 的進階 注意:本次操作是在上一個筆記的基礎之上 工程目錄如下: 1. 建立一個 EmployeeMapper 的介面 public interface EmployeeMapper { public Employee ge
MyBatis學習——第一個mybatis、MyBatis介面式程式設計、小結
第一個mybatis——helloWorld1、首先建立一張表,表結構、欄位型別如下所示:2、在intellij idea或eclipse中建立一個實體類Employee3、配置mybatis的配置檔案
Mybatis——實現介面式程式設計
通常情況下,都是使用SqlSession例項的selectXXX(selectOne, selectList, selectMap)方法來執行對映檔案中相應的SQL語句的,這些方法都有一個共同的特徵,那就是第一個引數都是String型別的,我們需要使用這個引數明
SQL執行異常系列之——隱式轉換
隱式 刷新 from cost exec ndt lte rownum varchar SQL> select object_id,CREATED from dba_objects where rownum < 10; OBJECT_ID CREATED
springboot2.x簡單詳細教程--高階篇幅之響應式程式設計(第十五章)
一、SprinBoot2.x響應式程式設計簡介 簡介:講解什麼是reactive響應式程式設計和使用的好處 1、基礎理解:  
MyBatis3-topic04,05 -介面式程式設計
筆記要點 /**介面式程式設計: * 1. 原生: Dao 介面-->Dao介面的實現類 * mybatis: Mapper --> 有一個與之對應的 XXMapper.xml * 2. SqlSession * 代表與資料庫的一次會話,用完必須關閉資源;
mybatis系列之XML對映檔案
一、XML對映檔案 1.1 Mybatis的增刪改操作 mybatis允許增刪改直接定義以下型別返回值 Integer、Long、Boolean、void 1.2 sqlsession sqlSessionFactory.openSession(); 獲取的
mybatis系列之入門和XML配置
一、為什麼使用mybatis 1.1 JDBC處理過程 JDBC功能簡單,一般需要上門五個過程即可; sql語句編寫在java程式碼裡面;硬編碼高耦合的方式; 維護不易且實際開發需求中sql是有變化,頻繁修改的情況多見 ; JDBC這種方式一般不推薦。其他框
Vue 進階系列之響應式原理及實現
什麼是響應式Reactivity Reactivity表示一個狀態改變之後,如何動態改變整個系統,在實際專案應用場景中即資料如何動態改變Dom。 需求 現在有一個需求,有a和b兩個變數,要求b一直是a的10倍,怎麼做? 簡單嘗試1: let a = 3; let b
MyBatis系列之TypeHandler的使用
MyBatis中TypeHandler的使用 題外話(閱讀原始碼所得): 在使用MyBatis的過程中,如果同時使用xml對映與Annotation,啟動會報錯,報錯原因:
Qt學習之介面UI程式設計應用
Qt作為c++的GUI程式設計框架,在Qt4時代,一直是傳統的基於QtWidget的C++程式設計,而到了Qt5,為了適用當前的移動應用開發浪潮,Qt提供了,另一套介面框架QtQuick,它是基於QML語言(類似於js)的程式設計,就一個特點:快!。編碼量大大減少。 這兩套框架雖說用不同的語言開
WebFlux基礎之響應式程式設計
上篇文章,我們簡單的瞭解了WebFlux的一些基礎與背景,並通過示例來寫了一個demo。我們知道WebFlux是響應式的web框架,其特點之一就是可以通過函數語言程式設計方式配置route。另外究竟什麼是響應式程式設計呢?這篇文章我們就簡單探討一下 一、Java8中的函數語言程式設計 百科中這樣定
江疏影讀書系列之Java併發程式設計實戰(第一章 簡介)
欲速則不達,欲達則欲速! 12年畢業,化工、零售。16年轉行,Java培訓五個月,17年1月,我人生中最悲慘的一個月,找工作處處
Java併發程式設計系列之十七 Condition介面
通過前面的文章,我們知道任何一個Java物件,都擁有一組監視器方法,主要包括wait()、notify()、notifyAll()方法,這些方法與synchronized關鍵字配合使用可以實現等待/通知機制。而且前面我們已經使用這種方式實現了生產者-消費者模式。類似地
MyBatis入門實驗(2)之介面程式設計
實驗內容 在上一章中,實現了直接通過 sqlSession 執行指定的SQL語句,但如果SqlID拼寫出錯,或者是入引數據型別不正確都可能導致執行時異常,並不能在編譯階段檢查出來。 本次實驗將使用 mybatis 的介面類的方式執行SQL語句從資料庫中取出資