MyBatis實(shí)戰(zhàn)總結(jié)

MyBatis的前身是iBatis,它是一個(gè)數(shù)據(jù)持久層框架。封裝優(yōu)化了普通JDBC的過(guò)程,如數(shù)據(jù)庫(kù)連接的創(chuàng)建、設(shè)置SQL語(yǔ)句參數(shù)、執(zhí)行SQL語(yǔ)句、事務(wù)、結(jié)果映射以及資源釋放等。

MyBatis是一個(gè)支持普通SQL查詢(xún)、存儲(chǔ)過(guò)程和高級(jí)映射的優(yōu)秀持久層框架,使用簡(jiǎn)單的XML或注解用于配置和原始映射,將POJO和數(shù)據(jù)庫(kù)記錄進(jìn)行相互映射。

MyBatis框架分析

我們知道最基礎(chǔ)的JDBC操作為以下七個(gè)步驟:

(1)加載JDBC驅(qū)動(dòng)

(2)建立并獲取數(shù)據(jù)庫(kù)連接

(3)創(chuàng)建JDBC Statement對(duì)象

(4)設(shè)置SQL語(yǔ)句的傳入?yún)?shù)

(5)執(zhí)行SQL語(yǔ)句并獲得結(jié)果

(6)處理執(zhí)行結(jié)果

(7)釋放相關(guān)資源

數(shù)據(jù)庫(kù)連接的創(chuàng)建、獲取和釋放代碼是可以復(fù)用的,而且每一次操作都進(jìn)行數(shù)據(jù)庫(kù)連接的創(chuàng)建和關(guān)閉是沒(méi)有必要的,是浪費(fèi)資源和影響性能的。使用數(shù)據(jù)庫(kù)連接池能夠很好的解決這些問(wèn)題。由于可能會(huì)使用不同的連接池,比如采用DBCP的連接池,或者采用容器本身的JNDI數(shù)據(jù)庫(kù)連接池,所以可以通過(guò)DataSource進(jìn)行解耦。

使用Spring容器進(jìn)行管理的MyBatis數(shù)據(jù)庫(kù)連接池配置代碼如:

基礎(chǔ)的JDBC進(jìn)行操作數(shù)據(jù)庫(kù)時(shí),是在Java類(lèi)中拼裝SQL語(yǔ)句進(jìn)行執(zhí)行。為了更簡(jiǎn)單易用以及更高的性能,MyBatis也是采用手寫(xiě)SQL,而不是通過(guò)復(fù)雜的配置來(lái)自動(dòng)生成SQL(這兩種方式的持久化框架俗稱(chēng)“半自動(dòng)化”和“全自動(dòng)化”,MyBatis是“半自動(dòng)化”的翹楚,“全自動(dòng)化”的代表則是hibernate。這兩個(gè)持久化框架都非常流行,而且各有自己的長(zhǎng)處,可以根據(jù)需求適當(dāng)應(yīng)用)。SQL放在Java類(lèi)里會(huì)有很多麻煩,第一,可讀性太差了,分散在各個(gè)Java類(lèi)里不利于維護(hù)和復(fù)用;第二,改動(dòng)Java代碼還要重新編譯部署。所以需要有統(tǒng)一的文件來(lái)存放相關(guān)的SQL。

XML文件可以自定義標(biāo)簽,而且可以使用#{參數(shù)名}的占位符來(lái)標(biāo)識(shí)參數(shù),同時(shí)可以引入JSTL中的等這樣的標(biāo)簽來(lái)設(shè)置動(dòng)態(tài)SQL,所以MyBatis中一般定義***Mapper.xml文件來(lái)保存SQL。在數(shù)據(jù)操作中,需要有真正的Java對(duì)象來(lái)承接外部調(diào)用。所以***Mapper.xml文件會(huì)有相對(duì)應(yīng)的一個(gè)***Mapper.java接口文件,框架暴露這些Mapper對(duì)象來(lái)和服務(wù)層進(jìn)行對(duì)接。

MyBatis通過(guò)約定及配置來(lái)銜接各個(gè)操作。Mapper.java類(lèi)中的方法名和Mapper.xml中SQL語(yǔ)句的id定義成相同的進(jìn)行映射;配置#{參數(shù)名}來(lái)匹配對(duì)應(yīng)的參數(shù)。返回結(jié)果可能為POJO、Map、List等類(lèi)型,所以我們需要定義清楚返回結(jié)果類(lèi)型,在SQL語(yǔ)句中需要定義resultMap屬性值;執(zhí)行的結(jié)果和返回的POJO對(duì)象的數(shù)據(jù)結(jié)構(gòu)怎么映射,在Mapper.xml文件需要配置映射的POJO對(duì)象以及屬性。

Mapper.xml、Mapper.java和POJO對(duì)象這三個(gè)文件是相輔相成的。業(yè)務(wù)開(kāi)發(fā)中也一般只是需要新增這三個(gè)文件內(nèi)容,數(shù)據(jù)庫(kù)連接和事務(wù)配置這些構(gòu)架好后是不太變動(dòng)的。有工具根據(jù)表結(jié)構(gòu)來(lái)生成這三個(gè)文件,用不用就再說(shuō)了。

總體來(lái)說(shuō),MyBatis框架定義Mapper對(duì)象來(lái)承接外部的調(diào)用,框架本身封裝了SqlSession、SqlSessionFactory來(lái)進(jìn)行數(shù)據(jù)庫(kù)連接;封裝了StatementHandler、Executor來(lái)執(zhí)行數(shù)據(jù)庫(kù)操作;封裝了ResultSetHandler來(lái)處理查詢(xún)結(jié)果。我們只需要架構(gòu)好 SqlSessionFactory的建立方式以及事務(wù)管理,根據(jù)業(yè)務(wù)提供Mapper對(duì)象。Mybatis結(jié)合Spring容器管理是一個(gè)不錯(cuò)的選擇。

MyBatis使用中幾點(diǎn)經(jīng)驗(yàn)

手動(dòng)增量配置映射文件

當(dāng)有工具生成Mapper等配置文件的時(shí)候,很多人就不愿意手動(dòng)寫(xiě)了。其實(shí)MyBatis的生成工具不是特別有用,生成的方法幾乎不可用,刪刪改改老半天還不如自己手寫(xiě)快。而且需要新加或修改屬性、方法時(shí),也是沒(méi)法使用生成的文件,因?yàn)樾枰A艉迷械囊恍傩院头椒?。手?xiě)映射文件時(shí)先定義出用到的字段,這樣配置文件會(huì)簡(jiǎn)潔清晰,同時(shí)結(jié)果映射時(shí)效率會(huì)更高。

Mapper層參數(shù)為Map時(shí),由Service層負(fù)責(zé)重載

Mapper中存在著很多類(lèi)似方法,可能是分別根據(jù)字段來(lái)查詢(xún)記錄,或者根據(jù)某幾個(gè)字段來(lái)查詢(xún)。由于不能重載以及為了減少冗余代碼,參數(shù)一般設(shè)置成Map。但參數(shù)設(shè)為Map會(huì)使代碼含義模糊,所以需要在service層來(lái)實(shí)現(xiàn)重載,對(duì)外提供的Service是代碼自解釋的??梢愿鶕?jù)具體的參數(shù)不同分別調(diào)用不同的service方法。

盡量少用if choose等語(yǔ)句

Mybatis的配置SQL時(shí),盡量少用if choose 等標(biāo)簽,能用SQL實(shí)現(xiàn)判斷的盡量用SQL來(lái)判斷(CASE WHEN ,DECODE等),可提高查詢(xún)性能以及便于維護(hù)。

我們來(lái)看看這樣的SQL:

SELECT * FROM USER WHERE

AND CREATE_DATE >= #{startdate} AND CREATE_DATE <= #{enddate}

AND CREATE_DATE >= SYSDATE - 7 AND CREATE_DATE <= SYSDATE

這樣的if判斷,其實(shí)是完全沒(méi)有必要的,我們可以很簡(jiǎn)單的采用DECODE來(lái)解決默認(rèn)值問(wèn)題:

SELECT * FROM USER WHERE

CREATE_DATE >= DECODE(#{startdate},NULL,SYSDATE-7, #{startdate})

AND CREATE_DATE <= DECODE(#{enddate},NULL,SYSDATE,#{enddate})

不過(guò)if與choose判斷分支是不可能完全去除的,但是推薦使用SQL原生的方式來(lái)解決一些動(dòng)態(tài)問(wèn)題,而不應(yīng)該完全依賴(lài)Mybatis來(lái)完成動(dòng)態(tài)分支的判斷,因?yàn)榕袛喾种н^(guò)于復(fù)雜,而且難以維護(hù)。

本文作者:王文(點(diǎn)融黑幫),畢業(yè)于帝都仰望星空大學(xué)軟件工程專(zhuān)業(yè),致力于大型分布式網(wǎng)站的建設(shè)。平時(shí)對(duì)用戶(hù)增長(zhǎng)、數(shù)據(jù)分析等方面比較關(guān)注。原始?jí)粝胧浅蔀橐粋€(gè)優(yōu)秀的個(gè)人站長(zhǎng),傳播分享好東西。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 簡(jiǎn)介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲(chǔ)過(guò)程以及高級(jí)映射的優(yōu)秀的...
    笨鳥(niǎo)慢飛閱讀 6,248評(píng)論 0 4
  • Java數(shù)據(jù)持久化之mybatis 一. mybatis簡(jiǎn)介 1.1 原始的JDBC操作: Java 通過(guò) Jav...
    小Q逛逛閱讀 5,409評(píng)論 0 16
  • 1 引言# 本文主要講解JDBC怎么演變到Mybatis的漸變過(guò)程,重點(diǎn)講解了為什么要將JDBC封裝成Mybait...
    七寸知架構(gòu)閱讀 77,559評(píng)論 36 979
  • 官方文檔 簡(jiǎn)介 入門(mén) XML配置 XML映射文件 動(dòng)態(tài)SQL Java API SQL語(yǔ)句構(gòu)建器 日志 一、 JD...
    拾壹北閱讀 3,657評(píng)論 0 52
  • 北方的氣溫剛升到零上五度,平時(shí)寂靜的廣場(chǎng)便有了生機(jī)。走圈的,遛狗的,聚堆閑聊的人們讓廣場(chǎng)頓時(shí)熱鬧起來(lái),當(dāng)然還少不了...
    千帆過(guò)盡z閱讀 312評(píng)論 0 0

友情鏈接更多精彩內(nèi)容