日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

MyBatis+Spring MVC开发指南(一)

發(fā)布時(shí)間:2025/3/21 javascript 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MyBatis+Spring MVC开发指南(一) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言


MyBatis+Spring MVC這套組合,在實(shí)際互聯(lián)網(wǎng)項(xiàng)目中非常流行,博主工作中也涉及過,打算由淺入深、系統(tǒng)的寫出來!這個(gè)系列將會(huì)涵蓋MyBatis開發(fā)詳解、Spring MVC開發(fā)詳解,以及2者的結(jié)合使用,并會(huì)分析它們的原理!(可以參考博主的另一篇文章了解Spring MVC原理:《寫出我的第一個(gè)框架:迷你版Spring MVC》)

?

沒有MyBatis之前


在早期,我們都是通過原生的JDBC來操作數(shù)據(jù)庫的,而這種方式存在很多問題。

我們先來看一個(gè)例子:

原生JDBC操作方式

?

問題有哪些呢?

第一,在創(chuàng)建數(shù)據(jù)庫連接這塊,程序是需要時(shí)創(chuàng)建,用完后關(guān)閉。如果頻繁的創(chuàng)建、關(guān)閉數(shù)據(jù)庫連接,顯然存在問題。當(dāng)然,我們可以通過數(shù)據(jù)庫連接池來處理這個(gè)問題。

第二,硬編碼的地方太多了。比如,數(shù)據(jù)庫連接相關(guān)的一些信息,SQL相關(guān)的一些信息。當(dāng)然,我們可以通過使用配置文件,來避免這個(gè)問題。

第三,實(shí)質(zhì)上,我們編寫JDBC是有步驟可循的,比如,我們得先得到數(shù)據(jù)庫連接對(duì)象,得有SQL,有輸入?yún)?shù),設(shè)置參數(shù),去執(zhí)行SQL,然后遍歷結(jié)果集將數(shù)據(jù)庫SQL執(zhí)行的結(jié)果對(duì)象轉(zhuǎn)化為JAVA對(duì)象,然后再去業(yè)務(wù)處理,最后釋放資源。那么這個(gè)過程,實(shí)際上是個(gè)模板,能不能抽離出來,更好的去完成這個(gè)過程呢?

比如,Hibernate,這個(gè)純粹的ORM(對(duì)象關(guān)系映射)框架,讓程序員以面向?qū)ο蟮姆绞絹硗瓿蓴?shù)據(jù)庫的操作,功能很強(qiáng)大,SQL都幫我們自動(dòng)生成了,但是這也帶來了一些其他問題,比如門檻較高,有時(shí)候我們想編寫SQL,修改SQL,優(yōu)化SQL都費(fèi)勁,在互聯(lián)網(wǎng)項(xiàng)目快速迭代開發(fā)中,太過笨重了!

基于這些因素,出現(xiàn)了iBatis,并發(fā)展為今天的MyBatis,作為Apache的頂級(jí)項(xiàng)目,目前已經(jīng)托管到github下。

?

MyBatis框架的架構(gòu)


上面我們說了一些JDBC的缺點(diǎn),而MyBatis是避免了這些問題的。如果讓我們來實(shí)現(xiàn)MyBatis的話,我們會(huì)怎么想呢?

第一,應(yīng)該存在一個(gè)配置文件A,可以將數(shù)據(jù)庫的連接信息,事務(wù)信息等放入其中;

第二,應(yīng)該提供一個(gè)配置文件B,可以讓程序員編寫SQL,重點(diǎn)需要解決的是如何給SQL傳遞參數(shù),以及如何將結(jié)果映射為JAVA對(duì)象;

第三,應(yīng)該提供API可以執(zhí)行文件B中的SQL

基于上面的分析,我們來看一下MyBatis的架構(gòu):

MyBatis的架構(gòu)

?

這里,我們先簡單了解些概念:

SqlSessionFactory用于創(chuàng)建SqlSession,SqlSession即操作DB的接口,其內(nèi)部借助Executor執(zhí)行器完成對(duì)數(shù)據(jù)庫的操作。

全局配置文件,就是圖中的SqlMapConfig.xml;SQL文件即是Mapper.xml文件。

對(duì)于MappedStatement而言,會(huì)完成輸入映射以及輸出映射。

?

Quick Start


這里先寫個(gè)簡單的DEMO帶大家初步了解下。

POM依賴:

pom.xml

?

MyBatis的全局配置文件:

SqlMapConfig.xml

?

需要注意下:

第一,我們把MySQL的一些連接信息放入到db.properties中,使用<properties>標(biāo)簽加載屬性文件,并通過${XXX}的方式引用。

第二,要知道現(xiàn)在的日志框架有很多,這里使用<settings>設(shè)置下日志使用LOG4J實(shí)現(xiàn)。

第三,我們說SQL結(jié)果集要完成到JAVA對(duì)象的映射,那么根據(jù)反射的原理,我們都能猜到必須要提供帶包路徑的全限定名稱,那么為了簡化,提供<typeAliases>標(biāo)簽進(jìn)行別名映射處理。提供了2種方式,一個(gè)是單個(gè)的類型別名映射,一個(gè)是基于包掃描的批量映射。當(dāng)然批量映射的別名就是類名。

第四,需要<mappers>標(biāo)簽加載SQL文件。同上面一樣,也提供了基于包掃描的批量加載。

log4j.properties:

log4j.properties

?

在開發(fā)階段,顯然,我們希望MyBatis能夠?yàn)槲覀兇蛴QL日志,方便調(diào)試,排查問題。

SQL配置:

Student.xml

?

需要關(guān)注下:

第一,namespace,顧名思義,命名空間,其實(shí)是想隔離SQL,不過到了MyBatis和Spring結(jié)合使用時(shí),具有特殊的意義。這里暫且使用全限定類名。

第二,<select>等SQL Command標(biāo)簽需要一個(gè)ID,還需要輸入?yún)?shù)parameterType,輸出參數(shù)映射resultType等。其實(shí)這些在MyBatis的底層封裝成了一個(gè)MappedStatement對(duì)象。當(dāng)然定位這個(gè)對(duì)象,需要namespace.id的方式。

第三,${value} VS #{xxx}

其實(shí)2者,都可以接受JAVA簡單類型,如int,也可以接受POJO,Map等復(fù)雜類型。如果是JAVA簡單類型,那么$的方式必須是${value},而#{}可以隨意,是因?yàn)樵谶@種情況下,$會(huì)通過反射getValue()的方式取值。如果是POJO等復(fù)雜類型,2者其實(shí)都可以通過OGNL表達(dá)式取到,只不過#會(huì)額外的進(jìn)行JAVA類型到數(shù)據(jù)庫類型的轉(zhuǎn)換,而$沒有類型處理過程,它直接拼接。也就是說#會(huì)使用預(yù)編譯成?,而$將在SQL編譯階段就采取替換操作,可能帶來SQL注入的問題。所以在實(shí)際開發(fā)中,我們當(dāng)然優(yōu)先采用#的方式取值。

測(cè)試程序:

Test

?

測(cè)試程序,并沒有太多可以說的,關(guān)注2點(diǎn)即可:

第一,selectOne VS selectList

顯然,我們需要清楚的知道,SQL返回的結(jié)果集是一條記錄,還是多條記錄,如果使用selectOne那么必須最多返回一條記錄。那么返回多條記錄與返回一條記錄的時(shí)候,resultType有變化么?(其實(shí)是不變的。)

第二,SqlSession

SqlSessionFactoryBuilder -> SqlSessionFactory -> SqlSession

我們重點(diǎn)關(guān)注的是SqlSession,它其實(shí)是一個(gè)interface,定義了很多操作數(shù)據(jù)庫的接口,而且extends Closeable,很明確是需要close的。

它的實(shí)現(xiàn)類DefaultSqlSession中有一些數(shù)據(jù)域(比如說autoCommit,在默認(rèn)情況下是不開啟自動(dòng)提交的),而且方法也并不是Synchronized,這說明SqlSession并不是線程安全的,因此我們應(yīng)該是局部使用SqlSession,使用完畢后close掉。

?

Mapper代理開發(fā)


其實(shí),除了Mapper代理開發(fā)外,還有一種原始Dao開發(fā)的方式。原始Dao開發(fā)方式的思路大致是這樣的:

第一,我們提供Dao接口,有增、刪、改、查的方法。

第二,我們提供Dao的實(shí)現(xiàn)類,在實(shí)現(xiàn)類中,我們利用Spring注入SqlSessionFactory,然后在各個(gè)方法中得到SqlSession,進(jìn)行操作后,關(guān)閉SqlSession即可。

這種方式,重復(fù)的代碼太多,已經(jīng)OUT了,目前使用最多的就是Mapper代理開發(fā)。

提供Mapper.java接口:

Mapper接口

?

提供與之對(duì)應(yīng)的Mapper.xml文件:

StudentMapper.xml

?

在全局配置文件中加載Mapper.xml:

加載mapper.xml配置

?

測(cè)試代碼示例:

調(diào)用方式

?

從這里,你應(yīng)該可以看出Mapper的開發(fā)應(yīng)該遵循一些規(guī)范,這樣MyBatis才可以自動(dòng)幫助我們生成XXXMapper類的代理實(shí)現(xiàn)類。(說白了,這些規(guī)范,就是為了利用反射)

第一,保證XXXMapper.xml中的namespace同XXXMapper.java的全限定名稱一致

第二,保證XXXMapper.xml中的Statement的ID同XXXMapper.java的方法名稱一致

第三,保證XXXMapper.xml中的Statement的輸入?yún)?shù)的類型(parameterType)、輸出參數(shù)的類型(resultType)同XXXMapper.java的保持一致

從這里,你大致可以了解到Mapper代理開發(fā),程序員主要關(guān)注的就是Mapper.java以及Mapper.xml的生成,可以說極大的簡化了工作量!

?

關(guān)于自增主鍵返回


很多時(shí)候,我們面臨這樣的需求,A表的字段ID是主鍵,而且是auto_increment自動(dòng)增長的;我們完成A表的插入后,希望得到主鍵,以便后續(xù)的操作,比如另外一個(gè)表B,和表A存在主外鍵關(guān)系。

MyBatis當(dāng)然早就替我們想好了,只需要稍微配置下,就可以將MySQL自動(dòng)生成的主鍵取出設(shè)置到對(duì)應(yīng)的JAVA對(duì)象的屬性上。

看一個(gè)例子:

自動(dòng)獲取主鍵設(shè)置

?

特別注意keyProperty是表示將獲取到的自動(dòng)增長的值設(shè)置到哪個(gè)Field域上。

?

關(guān)于動(dòng)態(tài)SQL


我們知道,在JSP中,可以使用JSTL標(biāo)簽開發(fā);而動(dòng)態(tài)SQL就是類似于JSTL的一組標(biāo)簽,可以幫助我們靈活的生成SQL,比如實(shí)現(xiàn)判斷,遍歷數(shù)組/集合,SQL片段的復(fù)用等。值得關(guān)注的是,有些標(biāo)簽還挺智能,比如<where>還可以替你去掉第一個(gè)and.....

本篇博客并不會(huì)說明各個(gè)標(biāo)簽的使用方式,這樣的例子,網(wǎng)上很多,大家可以參考。一句話,在開發(fā)階段,我們只需要讓MyBatis打印SQL,我們就能明白,我們的動(dòng)態(tài)SQL是不是使用對(duì)了!

?

到這里,本篇博客就準(zhǔn)備結(jié)束了,下一篇博客將會(huì)為大家介紹MyBatis的一些高級(jí)開發(fā)知識(shí)~

See U next time~



作者:張豐哲
鏈接:https://www.jianshu.com/p/91a32e3d4b26
來源:簡書
簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請(qǐng)聯(lián)系作者獲得授權(quán)并注明出處。

總結(jié)

以上是生活随笔為你收集整理的MyBatis+Spring MVC开发指南(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。