Mybatis進修總結之mybatis應用建議。本站提示廣大學習愛好者:(Mybatis進修總結之mybatis應用建議)文章只能為提供參考,不一定能成為您想要的結果。以下是Mybatis進修總結之mybatis應用建議正文
簡介:甚麼是MyBatis?
(前身為iBatis) MyBatis 是一個可以自界說SQL、存儲進程和高等映照的耐久層框架。MyBatis清除了簡直一切的JDBC代碼和參數的手工設置和對成果集的檢索。MyBatis可使用簡略的XML或注解用於設置裝備擺設和原始映照,將接口和Java的POJO(Plain Old Java Objects,通俗的Java對象)映照成數據庫中的記載。
1.Mapper層參數為Map,由Service層擔任重載。
Mapper因為機制的成績,不克不及重載,參數普通設置成Map,但如許會使參數變得隱約,假如想要使代碼變得清楚,可以經由過程service層來完成重載的目標,對外供給的Service層是重載的,但這些重載的Service辦法實際上是調統一個Mapper,只不外響應的參數其實不分歧。
或許有人會想,為何不在Service層也設置成Map呢?我小我是不推舉這麼做的,固然為了便利,我在之前的項目中也年夜量采取了這類方法,但很顯著會給往後的保護任務帶來費事。由於這麼做會使你全部MVC都依附於Map模子,這個模子實際上是很不錯的,便利搭框架,但存在一個成績:僅僅看辦法簽名,你不清晰Map中所具有的參數個數、類型、每一個參數代表的寄義。
試想,你只對Service層變革,或許DAO層變革,你須要清晰全部流程中Map傳遞過去的參數,除非你正文或許文檔優越,不然必需把每層的代碼都懂得清晰,你才曉得傳遞了哪些參數。針關於簡略MVC,那倒也還好,但假如條理龐雜以後,代碼會變得異常龐雜,並且假如我增長一個參數,須要把每個層的正文都添加上。絕對於正文,應用辦法簽名來包管這類代碼可控性會來得更可行一些,由於正文有能夠是過時的,但辦法簽名普通不太能夠是陳腐的。
2.盡可能罕用if choose等語句,下降保護的難度。
Mybatis的設置裝備擺設SQL時,盡可能罕用if choose 等標簽,能用SQL完成斷定的盡可能用SQL來斷定(CASE WHEN ,DECODE等),以便前期保護。不然,一旦SQL收縮,超等惡心,假如須要調試Mybatis中的SQL,須要去除年夜量的斷定語句,異常費事。另外一方面,年夜量的if斷定,會使生成的SQL中包括年夜量的空格,增長收集傳輸的時光,也弗成取。
並且年夜量的if choose語句,弗成防止地,每次生成的SQL會不太分歧,會招致ORACLE年夜量的硬解析,也弗成取。
我們來看看如許的SQL:
<code class="hljs sql" ><span class="hljs-operator" ><span class="hljs-keyword" >SELECT</span> * <span class="hljs-keyword" >FROM</span> T_NEWS_TEXT <span class="hljs-keyword" >WHERE</span> <span class="hljs-number" >1</span> = <span class="hljs-number" >1</span> < <span class="hljs-keyword" >choose</span>> < <span class="hljs-keyword" >if</span> test =<span class="hljs-string" >"startdate != null and startdate != '' and enddate != null and endate != ''"</span>> <span class="hljs-keyword" >AND</span> PUBLISHTIME >= #{startdate} <span class="hljs-keyword" >AND</span> PUBLISHTIME <= #{enddate} </ <span class="hljs-keyword" >if</span>> <otherwise> <span class="hljs-keyword" >AND</span> PUBLISHTIME >= <span class="hljs-keyword" >SYSDATE</span> - <span class="hljs-number" >7</span> <span class="hljs-keyword" >AND</span> PUBLISHTIME <= <span class="hljs-keyword" >SYSDATE</span> </otherwise></ <span class="hljs-keyword" >choose</span> ></span>
如許的if斷定,實際上是完整沒有需要的,我們可以很簡略的采取DECODE來處理默許值成績:
<code class="hljs sql" ><span class="hljs-operator" ><span class="hljs-keyword" >SELECT</span> * <span class="hljs-keyword" >FROM</span> T_NEWS_TEXT <span class="hljs-keyword" >WHERE</span> PUBLISHTIME >= <span class="hljs-keyword" >DECODE</span>(#{startdate},<span class="hljs-literal" >NULL</span>,<span class="hljs-keyword" >SYSDATE</span>-<span class="hljs-number" >7</span>, #{startdate}) <span class="hljs-keyword" >AND</span> PUBLISHTIME <= <span class="hljs-keyword" >DECODE</span>(#{enddate},<span class="hljs-literal" >NULL</span>,<span class="hljs-keyword" >SYSDATE</span>,#{enddate})</span></code>
固然有人會想,引入CASE WHEN,DECODE會招致須要ORACLE函數解析,會拖慢SQL履行時光,有興致的同窗可以歸去做一下測試,看看能否會有年夜的影響。就小我經歷而言,在我的開辟進程,沒有發明由於函數解析招致SQL變慢的情況。影響SQL履行效力的普通情形下是JOIN、ORDER BY、DISTINCT、PARTITATION BY等這些操作,這些操作普通與表構造設計有很年夜的聯系關系。絕對於這些的效力影響水平,函數解析關於SQL履行速度影呼應該是可以疏忽不計的。
別的一點,關於一些默許值的賦值,像下面那條SQL,默許成以後日期甚麼的,其實可以完整提到Service層或Controller層做處置,在Mybatis中應當要罕用這些斷定。由於,如許的話,很難做緩存處置。假如startdate為空,在SQL上應用靜態的SYSDATE,就沒法肯定緩存startdate日期的key應當是甚麼了。所以參數最好在傳遞至Mybatis之前都處置好,如許Mybatis層也能削減部門if choose語句,同時也便利做緩存處置。
固然不應用if choose也其實不是相對的,有時刻為了優化SQL,不能不應用if來處理,好比說LIKE語句,固然普通不推舉應用LIKE,但假如存在應用的場景,盡量在不須要應用時刻去除LIKE,好比查詢文章題目,以進步查詢效力。 最好的方法是應用lucence等搜刮引擎來處理這類全文索引的成績。
總的來講,if與choose斷定分支是弗成能完整去除的,然則推舉應用SQL原生的方法來處理一些靜態成績,而不該該完整依附Mybatis來完成靜態分支的斷定,由於斷定分支過於龐雜,並且難以保護。
3.用XML正文代替SQL正文。
Mybatis華夏SQL的正文盡可能不要保存,正文會激發一些成績,假如須要應用正文,可以在XML頂用<!-- -->來正文,包管在生成的SQL中不會存在SQL正文,從而下降成績湧現的能夠性。如許做還有一個利益,就是在IDE中可以很清晰的辨別正文與SQL。
如今來談談正文激發的成績,我做的一個項目中,分頁組件是基於Mybatis的,它會在你寫的SQL劇本裡面再套一層SELECT COUNT(*) ROWNUM_ FROM (....) 盤算總記載數,同時有另外一個嵌套SELECT * FROM(...) WHERE ROWNUM > 10 AND RONNUM < 10 * 2這類方法生成份頁信息,假如你的劇本中最初一行湧現了正文,則添加的部門會成為正文的一部門,履行就會報錯。除此以外,某些情形下也能夠招致部門前提被疏忽,以下面的情形:
<code class="hljs vbnet" ><span class="hljs-keyword" >SELECT</span> * <span class="hljs-keyword" >FROM</span> TEST <span class="hljs-keyword" >WHERE</span> COL1 > <span class="hljs-number" >1</span> -- 這裡是正文<<span class="hljs-keyword" >if</span> test=<span class="hljs-string" >"a != null and a != ''"</span>><span class="hljs-keyword" >AND</span> COL2 = <span class="hljs-preprocessor" >#{a}</<span class="hljs-keyword" >if</span>></span></code>
即便傳入的參數中存在對應的參數,現實也不會發生後果,由於前面的內容現實上是被完整正文了。這類毛病,假如不經由嚴厲的測試,是很難發明的。普通情形下,XML正文完整可以替換SQL正文,是以這類行動應當可以制止失落。
4.盡量應用#{},而不是${}.
Mybatis中盡可能不要應用${},盡可能如許做很便利開辟,然則有一個成績,就是年夜量應用會招致ORACLE的硬解析,拖慢數據庫機能,運轉越久,數據庫機能會越差。關於普通多個字符串IN的處置,可以參考以下的處理計劃:http://www.myexception.cn/sql/849573.html,根本可以處理年夜部門${}.
關於${},另外一個誤用的處所就是LIKE,我這邊還有個案例:好比一些樹型菜單,節點會設計成'01','0101',用兩位節點來辨別層級,這時候候,假如須要查詢01節點下一切的節點,最簡略的SQL就是:SELECT * FROM TREE WHERE ID LIKE '01%',這類SQL其實無可厚非,由於它也能用到索引,所以不須要特殊的處置,直接應用就好了。但假如是文章題目,則須要額定留意了:SELECT * FROM T_NEWS_TEXT WHERE TITLE LIKE '%OSC%',這是怎樣也不會用到索引的,下面說了,最好采取全文檢索。但假如離不開LIKE,就須要留意應用的方法: ID LIKE #{ID} || '%'而不是ID LIKE '${ID}%',削減硬解析的能夠。
有人認為應用||會增長ORACLE處置的時光,我認為不要把ORACLE看得太傻,固然有時刻確切異常傻,有空可以再總結ORACLE傻不渣滓的處所,然則略加測試便知:這類串連方法,關於全部SQL的解析履行,應當是微不足道的。
固然還有一些特別情形是沒有方法處置的,好比說靜態注出列名、表名等。關於這些情形,則比擬辣手,沒有找到比擬便利的手腕。因為這類情形湧現的能夠性會比擬少,所以應用${}倒也不至於有甚麼太年夜的影響。固然你假如有代碼潔癖的話,可使用ORACLE的靜態履行SQL的機制Execute immediate,如許便可以完整防止${}湧現的能夠性了。如許會引入比擬龐雜的模子,這個時刻,你就須要棄取了。
針關於以上靜態SQL所招致的成績,最保守的方法是全體采取存儲進程,用數據庫原生的方法來處理,便利開辟調試,固然也會帶來成績:對開辟人員會有更高的請求、存儲進程的治理等等,我這邊項目沒有采取過這類方法,這裡不做更多的睜開。
5.簡略應用Mybatis。
Mybatis的功效絕對而言照樣比擬弱的,缺乏了很多多少需要的幫助庫,字符串處置等等,擴大也比擬艱苦,普通也便可能對前往值停止一些處置。是以最好僅僅把它作為純真的SQL設置裝備擺設文件,和簡略的ORM框架。不要測驗考試在Mybatis中做過量的靜態SQL,不然會招致後續的保護異常惡心。
以上所述是小編給年夜家引見的Mybatis進修總結之mybatis應用建議,願望對年夜家有所贊助,假如年夜家有任何疑問請給我留言,小編會實時答復年夜家的。在此也異常感激年夜家對網站的支撐!