mybatis入門-mapper代理原理

来源:http://www.cnblogs.com/liyasong/archive/2017/02/10/6387825.html
-Advertisement-
Play Games

我們都知道,在開發中只要按照一定的規範去配置的話,我們的mybatis是不需要寫mapper介面的實現類的,那麼mybatis到底是如何實現了讓我們可以不用寫mapper的實體類的呢?這裡寫了一下自己的看法,歡迎各位大神指導。 ...


  原始dao層開發

    在我們用mybatis開發了第一個小程式後,相信大家對於dao層的開發其實已經有了一個大概的思路了。其他的配置不用變,將原來的test方法,該為dao的方法,將原來的返回值,直接在dao層進行一下接收就可以了。依然是老一套,先是大框架,然後寫配置文件及UserMapper.xml文件這一系列的操作。如果不明白的,請參考本人博客《入門第一個程式》。

    我們需要做的就是,首先建立一個會話工廠(SqlSessionFactory),然後用會話工廠創建會話(SqlSession)。然後通過讀取配置文件得到sql語句,執行,然後返回數據給dao層的對象。具體操作如下

    首先,在原來的基礎上創建一個dao層的介面。

    

    然後寫一個dao層介面的實現類

 1 public class UserDaoImpl implements UserDao {
 2  
 3 // 需要向dao實現類中註入SqlSessionFactory
 4 // 這裡通過構造方法註入
 5 private SqlSessionFactory sqlSessionFactory;
 6  
 7 public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
 8 this.sqlSessionFactory = sqlSessionFactory;
 9 }
10  
11 @Override
12 public User findUserById(int id) throws Exception {
13 SqlSession sqlSession = sqlSessionFactory.openSession();
14  
15 User user = sqlSession.selectOne("test.findUserById", id);
16  
17 // 釋放資源
18 sqlSession.close();
19  
20 return user;
21  
22 }
23  
24 @Override
25 public void insertUser(User user) throws Exception {
26 SqlSession sqlSession = sqlSessionFactory.openSession();
27  
28 //執行插入操作
29 sqlSession.insert("test.insertUser", user);
30  
31 // 提交事務
32 sqlSession.commit();
33  
34 // 釋放資源
35 sqlSession.close();
36  
37 }
38  
39 @Override
40 public void deleteUser(int id) throws Exception {
41 SqlSession sqlSession = sqlSessionFactory.openSession();
42  
43 //執行插入操作
44 sqlSession.delete("test.deleteUser", id);
45  
46 // 提交事務
47 sqlSession.commit();
48  
49 // 釋放資源
50 sqlSession.close();
51  
52 }
53  
54 }

然後就是對我們寫的代碼的測試

    這樣開發的話有一些問題:

    1.dao介面的實現類中存在大量的重覆代碼,這些代碼會增加程式員的工作量。

    2.在實現類中,SqlSession的方法在調用映射文件中的sql語句時將statement的id(其中的"test.findUserById"便是statment的id)硬編碼了。

    

    3.調用SqlSession方法時傳入的變數,由於sqlsession方法使用泛型,即使變數類型傳入的不是Dao方法中的參數類型,在編譯的時候也不會報錯,不利於程式的開發。

    

    為瞭解決這些問題,我們通過滿足一些規範就將實體層的實現類的開發省去,由mybatis框架提供的代理實現類替我們去動態的調用我們的映射文件,然後去執行類中的方法。

  mapper代理方法的原理

    這之前,先聲明一下,使用mapper代理的時候,命名和之前的不太一樣。這裡的介面命名由原來的** 改為**Mapper,比如說原來的User介面,現改為UserMapper。其內容和本質沒有變,只是換了一個命名規範。除了介面外映射文件也是由User.xml改為UserMapper.xml其內容不變。

    mapper代理方法的思路是,程式員接著寫持久層的介面。

    

 

    和對應每個介面的配置文件。

    

   在我們的原來的方法中需要再寫一個介面的實現類,用來構建會話工廠(SqlSessionFactory)和對應的會話(SqlSession)然後通過會話去讀取映射文件中的sql語句(這裡不准確,不過可以這麼理解)。那麼我麽就可以在這個實體類上做點文章了:

    1.我們可以創建一個代理類,在我們相應的介面被調用的時候,代理類就會創建這個對象,創建會話工廠和會話並不難。

    2.還有就是我們的sqlSession對象調用的方法名稱,這個很好理解,對應的是我們映射文件的標簽。

    3.那麼接下來就是傳入參數和接收返回值的問題了:

    3.1 傳入參數:我們總共需要傳入兩個參數,一個是映射文件的statement的id的字元串,另外一個是執行需要的參數。 比較困難的是,這個字元串的生成問題。我們的每個方法到底對應的是哪個映射文件的statement的id。對於這個問題,mybatis給出了我們的解決方法:我們的實體層對象讀到的字元串是這樣的:test.insertUser

    可以將這個id分為兩部分,其中的test是我們的映射文件中的namespace的值,這個值讓它和持久層介面的地址一致,這樣就使得代理對象可以通過介面的地址動態的生成id的前半部分,也就是test的這一部分;而後半部分則是讓映射文件中的Statement的id和介面的方法一致。

    也就是說,用戶在調用介面的某一個方法的時候,mybatis可以根據介面地址和對應的方法名生成sqlsession對象的方法傳入的字元串。這樣就解決了傳入參數中的字元串的問題了。

    還有就是第二個問題:我們的傳入具體參數,mybatis規定,傳入參數類型必須和介面的傳入參數類型一致。這樣,我們的傳入參數類型就搞定了。

    3.2傳入參數搞定了以後,返回值也就搞定了,跟傳入參數的規定一樣,返回值的類型要求和介面返回值一致,這樣就可以在代理類中將返回值傳出了。

    這些搞定了,我們就可以使用代理對象代替我們的實體層具體實現類了。

    至此,這些問題就差不多都解決了,不過還有一個問題:我們的select方法返回值問題,代理對象到底是用selectont方法去查詢資料庫呢還是使用selectlist方法呢?這個跟我們的介面(mapper)的返回值類型有關——如果mapper方法返回單個pojo對象(非集合對象),代理對象內部通過selectOne查詢資料庫;如果mapper方法返回集合對象,代理對象內部通過selectList查詢資料庫。

  mapper代理方法

    原理講完了,使用其實就基本上沒啥要說的了。

    首先我們要創建一個介面。

    

    然後寫對應介面的xml文件(截取部分,namespace處就不截圖了)。

     

    最後別忘了在SqlMapConfig.xml文件中載入UserMapper.xml。

    

    測試,這裡有必要說一下,我們的代理對象是通過SqlSession.getMapper(介面位元組碼文件)獲取的。:

    

    至此,我們的mybatis的實體層的實體層實現類就可以省略不寫了。不過這樣做的壞處是加強了代碼的耦合性,每個介面和每個映射文件必須對應。不過還是感覺通過遵守一定的規範而使得代碼量大大減少更爽呢。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 轉眼就到了元宵節,匆匆忙忙的腳步是我們在為生活奮鬥的寫照,新的一年,我們應該努力讓自己有不一樣的生活和追求。生命不息,奮鬥不止。在上篇博文中主要介紹了.NET的AppDomain的相關信息,在本篇博文中將會主要說明.NET程式集、對象代理,以及對象的封送原理。 一.程式集解析: 談到程式集,就要知道 ...
  • //導出 private string outFileName = ""; private string fullFilename = ""; private Workbook book = null; private Worksheet sheet = null; private void Add ...
  • 剛下樓遛狗回來,想起來的時候已經過了凌晨... 房子已經面簽完了,下一步就是過戶了,一想到自己從此沒有輕鬆的日子過了就壓力山大 過年放假這幾天,我總算把自己的引擎的底層基礎類型,工具庫,IO系統調整完了,接下來要開始整理資源模塊了 我已經寫過四個正式上線項目的文件系統,打包,更新這一套邏輯和工具了, ...
  • Maven是個啥? Maven主要服務於基於Java平臺的項目構建、依賴管理和項目信息管理,並且Maven是跨平臺的,這意味著無論是在Windows上,還是在Linux或者Mac上,都可以使用同樣的命令。 構建(build)又是個啥? 每天來公司第一件事情就是拉取最新代碼,然後進行單元測試(如果失敗 ...
  • 有時遇到將數據傳輸對象轉換成JSON串會將屬性值為空的屬性去掉,利用Java反射實現JavaBean對象數據傳輸對象的相同屬性複製並初始化數據傳輸對象屬性為空的屬性,然後轉換成JSON串 package com.banksteel.util; import java.lang.reflect.Fie ...
  • 互聯網的發展,網站應用的規模不斷擴大,常規的垂直應用架構已無法應對,分散式服務架構以及流動計算架構勢在必行,Dubbo是一個分散式服務框架,在這種情況下誕生的。現在核心業務抽取出來,作為獨立的服務,使前端應用能更快速和穩定的響應。 第一:介紹Dubbo背景 大規模服務化之前,應用可能只是通過RMI或 ...
  • 原理:模板元程式由編譯器在編譯期解釋執行,利用模板特化機制實現編譯期條件選擇結構,利用遞歸模板實現編譯期迴圈結構。模板元編程(metaprogramming)意思是,編程系統將會執行我們所寫的代碼,來生成新的代碼,而這些新代碼才真正實現了我們所期望的功能。元編程最大的特點在於:某些用戶自定義的計算可 ...
  • STC12C5A60S2 一.根據晶元文檔連接物理電路,最小系統: 電路圖<>實物圖 二.根據usb下載器安裝驅動 1.先把usb下載器插到電腦,查看電腦設備管理,查看占用的com埠 如果設備未識別,需要安裝usb驅動 2.安裝keil編譯器 1>.新建一個工程,再新建一個源碼文件,再把文件添加 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...